aboutsummaryrefslogtreecommitdiff
path: root/VMProtect/mainwindow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'VMProtect/mainwindow.cc')
-rw-r--r--VMProtect/mainwindow.cc3712
1 files changed, 3712 insertions, 0 deletions
diff --git a/VMProtect/mainwindow.cc b/VMProtect/mainwindow.cc
new file mode 100644
index 0000000..70e27a7
--- /dev/null
+++ b/VMProtect/mainwindow.cc
@@ -0,0 +1,3712 @@
+#include "../core/objects.h"
+#include "../core/files.h"
+#include "../core/core.h"
+#include "../core/processors.h"
+#include "../core/script.h"
+#include "../core/lang.h"
+#include "../core/inifile.h"
+
+#include "models.h"
+#include "widgets.h"
+#include "property_editor.h"
+#include "progress_dialog.h"
+#include "mainwindow.h"
+#include "moc/moc_mainwindow.cc"
+#include "function_dialog.h"
+#ifdef ULTIMATE
+#include "license_dialog.h"
+#include "import_license_dialog.h"
+#include "export_key_pair_dialog.h"
+#endif
+#include "watermarks_window.h"
+#include "settings_dialog.h"
+#include "message_dialog.h"
+#include "about_dialog.h"
+#include "wait_cursor.h"
+#include "help_browser.h"
+#include "template_save_dialog.h"
+#include "templates_window.h"
+#include "application.h"
+
+#ifndef VMP_GNU
+// cannot include header - name conflict with our "Folder"
+#define CSIDL_COMMON_DOCUMENTS 0x002e // All Users\Documents
+SHSTDAPI_(BOOL) SHGetSpecialFolderPathW(__reserved HWND hwnd, __out_ecount(MAX_PATH) LPWSTR pszPath, __in int csidl, __in BOOL fCreate);
+#endif
+
+/**
+ * MainWindow
+ */
+
+MainWindow::MainWindow()
+ : QMainWindow(), temp_function_(NULL), fileChanged_(false)
+{
+ installEventFilter(this);
+
+ VMProtectBeginVirtualization("Caption");
+#ifdef DEMO
+ caption_ = QString::fromLatin1(Core::edition()).append(' ').append(QString::fromLatin1(VMProtectDecryptStringA("[demo]")));
+#else
+ bool is_registered = false;
+ {
+ VMProtectSerialNumberData serial_data;
+ if (VMProtectSetSerialNumber(VMProtectDecryptStringA("SerialNumber")) == SERIAL_STATE_SUCCESS && VMProtectGetSerialNumberData(&serial_data, sizeof(serial_data))) {
+ if (Core::check_license_edition(serial_data))
+ is_registered = true;
+ else
+ VMProtectSetSerialNumber(NULL);
+ }
+ }
+ caption_ = QString::fromLatin1(Core::edition()).append(' ').append(QString::fromLatin1(is_registered ? VMProtectDecryptStringA("[registered]") : VMProtectDecryptStringA("[unregistered]")));
+#endif
+ setWindowTitle(caption_);
+ VMProtectEnd();
+
+ // create internal objects
+ log_ = new GUILog(this);
+ connect(log_, SIGNAL(notify(MessageType, IObject *, const QString &)), this, SLOT(notify(MessageType, IObject *, const QString &)));
+
+ core_ = new Core(qobject_cast<ILog*>(log_));
+
+ watermarks_model_ = new WatermarksModel(this);
+ watermarks_model_->setCore(core_);
+ WatermarksWindow::setModel(watermarks_model_);
+
+ templates_model_ = new TemplatesModel(this);
+ templates_model_->setCore(core_);
+ TemplatesWindow::setModel(templates_model_);
+
+ project_model_ = new ProjectModel(this);
+ connect(project_model_, SIGNAL(modified()), this, SLOT(projectModified()));
+ connect(project_model_, SIGNAL(nodeRemoved(ProjectNode *)), this, SLOT(projectNodeRemoved(ProjectNode *)));
+ connect(project_model_, SIGNAL(objectRemoved(void *)), this, SLOT(projectObjectRemoved(void *)));
+
+ search_model_ = new SearchModel(this);
+ directory_model_ = new DirectoryModel(this);
+ log_model_ = new LogModel(this);
+ function_property_manager_ = new FunctionPropertyManager(this);
+ core_property_manager_ = new CorePropertyManager(this);
+#ifndef LITE
+ functions_model_ = new FunctionsModel(this);
+ info_model_ = new InfoModel(this);
+ connect(info_model_, SIGNAL(modified()), this, SLOT(projectModified()));
+
+ dump_model_ = new DumpModel(this);
+ disasm_model_ = new DisasmModel(this);
+ section_property_manager_ = new SectionPropertyManager(this);
+ segment_property_manager_ = new SegmentPropertyManager(this);
+ import_property_manager_ = new ImportPropertyManager(this);
+ export_property_manager_ = new ExportPropertyManager(this);
+ resource_property_manager_ = new ResourcePropertyManager(this);
+ loadcommand_property_manager_ = new LoadCommandPropertyManager(this);
+ address_calculator_manager_ = new AddressCalculator(this);
+#endif
+#ifdef ULTIMATE
+ license_property_manager_ = new LicensePropertyManager(this);
+ internal_file_property_manager_ = new InternalFilePropertyManager(this);
+ assembly_property_manager_ = new AssemblyPropertyManager(this);
+#endif
+
+ // create actions
+ QIcon icon = QIcon(":/images/open.png");
+ icon.addPixmap(QPixmap(":/images/open_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/open_disabled.png"), QIcon::Disabled, QIcon::Off);
+ open_act_ = new QAction(icon, QString::fromUtf8(language[lsOpen].c_str()) + "...", this);
+ open_act_->setShortcut(QString("Ctrl+O"));
+ connect(open_act_, SIGNAL(triggered()), this, SLOT(open()));
+
+ icon = QIcon(":/images/disk.png");
+ icon.addPixmap(QPixmap(":/images/disk_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/disk_disabled.png"), QIcon::Disabled, QIcon::Off);
+ save_act_ = new QAction(icon, QString::fromUtf8(language[lsSaveProject].c_str()), this);
+ save_act_->setShortcut(QString("Ctrl+S"));
+ save_act_->setEnabled(false);
+ connect(save_act_, SIGNAL(triggered()), this, SLOT(save()));
+
+ save_as_act_ = new QAction(QString::fromUtf8(language[lsSaveProjectAs].c_str()) + "...", this);
+ save_as_act_->setShortcut(QKeySequence::SaveAs);
+ save_as_act_->setEnabled(false);
+ connect(save_as_act_, SIGNAL(triggered()), this, SLOT(saveAs()));
+
+ close_act_ = new QAction(QString::fromUtf8(language[lsClose].c_str()), this);
+ close_act_->setShortcut(QString("Ctrl+W"));
+ close_act_->setEnabled(false);
+ connect(close_act_, SIGNAL(triggered()), this, SLOT(closeFile()));
+
+ exit_act_ = new QAction(QString::fromUtf8(language[lsExit].c_str()), this);
+ connect(exit_act_, SIGNAL(triggered()), this, SLOT(close()));
+
+ help_act_ = new QAction(QString::fromUtf8(language[lsContents].c_str()), this);
+ help_act_->setShortcut(HelpContentsKeySequence());
+ connect(help_act_, SIGNAL(triggered()), this, SLOT(help()));
+
+ home_page_act_ = new QAction(QString::fromUtf8(language[lsHomePage].c_str()), this);
+ home_page_act_->setToolTip("http://www.vmpsoft.com");
+ connect(home_page_act_, SIGNAL(triggered()), this, SLOT(homePage()));
+
+ about_act_ = new QAction(QString::fromUtf8(language[lsAbout].c_str()) + "...", this);
+ connect(about_act_, SIGNAL(triggered()), this, SLOT(about()));
+
+ undo_act_ = new QAction(QString::fromUtf8(language[lsUndo].c_str()), this);
+ undo_act_->setShortcut(QKeySequence::Undo);
+ undo_act_->setEnabled(false);
+ connect(undo_act_, SIGNAL(triggered()), this, SLOT(undo()));
+
+ redo_act_ = new QAction(QString::fromUtf8(language[lsRedo].c_str()), this);
+ redo_act_->setShortcut(QKeySequence::Redo);
+ redo_act_->setEnabled(false);
+ connect(redo_act_, SIGNAL(triggered()), this, SLOT(redo()));
+
+ icon = QIcon(":/images/cut.png");
+ icon.addPixmap(QPixmap(":/images/cut_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/cut_disabled.png"), QIcon::Disabled, QIcon::Off);
+ cut_act_ = new QAction(icon, QString::fromUtf8(language[lsCut].c_str()), this);
+ cut_act_->setShortcut(QKeySequence::Cut);
+ cut_act_->setEnabled(false);
+ connect(cut_act_, SIGNAL(triggered()), this, SLOT(cut()));
+
+ icon = QIcon(":/images/copy.png");
+ icon.addPixmap(QPixmap(":/images/copy_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/copy_disabled.png"), QIcon::Disabled, QIcon::Off);
+ copy_act_ = new QAction(icon, QString::fromUtf8(language[lsCopy].c_str()), this);
+ copy_act_->setShortcut(QKeySequence::Copy);
+ copy_act_->setEnabled(false);
+ connect(copy_act_, SIGNAL(triggered()), this, SLOT(copy()));
+
+ icon = QIcon(":/images/paste.png");
+ icon.addPixmap(QPixmap(":/images/paste_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/paste_disabled.png"), QIcon::Disabled, QIcon::Off);
+ paste_act_ = new QAction(icon, QString::fromUtf8(language[lsPaste].c_str()), this);
+ paste_act_->setShortcut(QKeySequence::Paste);
+ paste_act_->setEnabled(false);
+ connect(paste_act_, SIGNAL(triggered()), this, SLOT(paste()));
+
+ cut_act2_ = new QAction(cut_act_->icon(), QString::fromUtf8(language[lsCut].c_str()), this);
+ cut_act2_->setEnabled(false);
+ cut_act2_->setVisible(false);
+ connect(cut_act2_, SIGNAL(triggered()), this, SLOT(cut()));
+
+ copy_act2_ = new QAction(copy_act_->icon(), QString::fromUtf8(language[lsCopy].c_str()), this);
+ copy_act2_->setEnabled(false);
+ copy_act2_->setVisible(false);
+ connect(copy_act2_, SIGNAL(triggered()), this, SLOT(copy()));
+
+ paste_act2_ = new QAction(paste_act_->icon(), QString::fromUtf8(language[lsPaste].c_str()), this);
+ paste_act2_->setEnabled(false);
+ paste_act2_->setVisible(false);
+ connect(paste_act2_, SIGNAL(triggered()), this, SLOT(paste()));
+
+#ifdef LITE
+ icon = QIcon(":/images/check_off.png");
+ icon.addPixmap(QPixmap(":/images/check_on.png"), QIcon::Normal, QIcon::On);
+ icon.addPixmap(QPixmap(":/images/check_off_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/check_on_hover.png"), QIcon::Active, QIcon::On);
+ show_act_ = new QAction(icon, QString::fromUtf8(language[lsShowProtectedFunctions].c_str()), this);
+ show_act_->setCheckable(true);
+ show_act_->setVisible(false);
+ connect(show_act_, SIGNAL(triggered()), this, SLOT(showProtected()));
+#else
+ goto_act_ = new QAction(icon, QString::fromUtf8(language[lsGoTo].c_str()) + "...", this);
+ goto_act_->setShortcut(QString("Ctrl+G"));
+ goto_act_->setEnabled(false);
+ connect(goto_act_, SIGNAL(triggered()), this, SLOT(goTo()));
+
+ icon = QIcon(":/images/goto.png");
+ icon.addPixmap(QPixmap(":/images/goto_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/goto_disabled.png"), QIcon::Disabled, QIcon::Off);
+ goto_act2_ = new QAction(icon, QString::fromUtf8(language[lsGoTo].c_str()), this);
+ goto_act2_->setVisible(false);
+ connect(goto_act2_, SIGNAL(triggered()), this, SLOT(goTo()));
+
+ add_function_act_ = new QAction(QString::fromUtf8(language[lsAddFunction].c_str()) + "...", this);
+ add_function_act_->setEnabled(false);
+ connect(add_function_act_, SIGNAL(triggered()), this, SLOT(addFunction()));
+
+ add_folder_act_ = new QAction(QString::fromUtf8(language[lsAddFolder].c_str()) + "...", this);
+ add_folder_act_->setEnabled(false);
+ connect(add_folder_act_, SIGNAL(triggered()), this, SLOT(addFolder()));
+
+ icon = QIcon(":/images/add.png");
+ icon.addPixmap(QPixmap(":/images/add_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/add_disabled.png"), QIcon::Disabled, QIcon::Off);
+ add_function_act2_ = new QAction(icon, QString::fromUtf8(language[lsAddFunction].c_str()), this);
+ add_function_act2_->setShortcut(QString("Ins"));
+ add_function_act2_->setVisible(false);
+ connect(add_function_act2_, SIGNAL(triggered()), this, SLOT(addFunction()));
+
+ watermarks_act_ = new QAction(QString::fromUtf8(language[lsWatermarks].c_str()) + "...", this);
+ connect(watermarks_act_, SIGNAL(triggered()), this, SLOT(watermarks()));
+#endif
+
+#ifdef ULTIMATE
+ save_licenses_act_ = new QAction(QString::fromUtf8(language[lsSaveLicensesAs].c_str()) + "...", this);
+ save_licenses_act_->setEnabled(false);
+ connect(save_licenses_act_, SIGNAL(triggered()), this, SLOT(saveLicenses()));
+
+ add_license_act_ = new QAction(QString::fromUtf8(language[lsAddLicense].c_str()) + "...", this);
+ add_license_act_->setEnabled(false);
+ connect(add_license_act_, SIGNAL(triggered()), this, SLOT(addLicense()));
+ add_license_act2_ = new QAction(icon, QString::fromUtf8(language[lsAddLicense].c_str()), this);
+ add_license_act2_->setShortcut(QString("Ins"));
+ add_license_act2_->setVisible(false);
+ connect(add_license_act2_, SIGNAL(triggered()), this, SLOT(addLicense()));
+
+ add_file_act_ = new QAction((language[lsAddFile] + "...").c_str(), this);
+ add_file_act_->setEnabled(false);
+ connect(add_file_act_, SIGNAL(triggered()), this, SLOT(addFile()));
+ add_file_act2_ = new QAction(icon, QString::fromUtf8(language[lsAddFile].c_str()), this);
+ add_file_act2_->setShortcut(QString("Ins"));
+ add_file_act2_->setVisible(false);
+ connect(add_file_act2_, SIGNAL(triggered()), this, SLOT(addFile()));
+
+ import_license_act_ = new QAction(QString::fromUtf8(language[lsImportLicense].c_str()) + "...", this);
+ import_license_act_->setShortcut(QString("Ctrl+I"));
+ import_license_act_->setEnabled(false);
+ connect(import_license_act_, SIGNAL(triggered()), this, SLOT(importLicense()));
+
+ import_project_act_ = new QAction(QString::fromUtf8(language[lsImportLicensesFromProjectFile].c_str()) + "...", this);
+ import_project_act_->setShortcut(QString("Ctrl+Shift+I"));
+ import_project_act_->setEnabled(false);
+ connect(import_project_act_, SIGNAL(triggered()), this, SLOT(importProject()));
+
+ export_key_act_ = new QAction((language[lsExportKeyPair] + "...").c_str(), this);
+ export_key_act_->setEnabled(false);
+ connect(export_key_act_, SIGNAL(triggered()), this, SLOT(exportKeyPair()));
+#endif
+
+ delete_act_ = new QAction(QString::fromUtf8(language[lsDelete].c_str()), this);
+ delete_act_->setShortcut(QString("Del"));
+ delete_act_->setEnabled(false);
+ connect(delete_act_, SIGNAL(triggered()), this, SLOT(del()));
+
+ rename_act_ = new QAction(QString::fromUtf8(language[lsRename].c_str()), this);
+ rename_act_->setShortcut(QString("F2"));
+ rename_act_->setEnabled(false);
+ connect(rename_act_, SIGNAL(triggered()), this, SLOT(rename()));
+
+ exclude_act_ = new QAction(QString::fromUtf8(language[lsExcludedFromCompilation].c_str()), this);
+ exclude_act_->setEnabled(false);
+ exclude_act_->setCheckable(true);
+ connect(exclude_act_, SIGNAL(triggered()), this, SLOT(excludeFromCompilation()));
+
+ block_act_ = new QAction(QString::fromUtf8(language[lsBlocked].c_str()), this);
+ block_act_->setEnabled(false);
+ block_act_->setCheckable(true);
+ connect(block_act_, SIGNAL(triggered()), this, SLOT(block()));
+
+ icon = QIcon(":/images/compile.png");
+ icon.addPixmap(QPixmap(":/images/compile_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/compile_disabled.png"), QIcon::Disabled, QIcon::Off);
+ compile_act_ = new QAction(icon, QString::fromUtf8(language[lsCompile].c_str()), this);
+ compile_act_->setShortcut(QString("F9"));
+ compile_act_->setEnabled(false);
+ connect(compile_act_, SIGNAL(triggered()), this, SLOT(compile()));
+
+ icon = QIcon(":/images/execute.png");
+ icon.addPixmap(QPixmap(":/images/execute_hover.png"), QIcon::Active, QIcon::Off);
+ icon.addPixmap(QPixmap(":/images/execute_disabled.png"), QIcon::Disabled, QIcon::Off);
+ execute_act_ = new QAction(icon, QString::fromUtf8(language[lsExecute].c_str()), this);
+ execute_act_->setShortcut(QString("F5"));
+ execute_act_->setEnabled(false);
+ connect(execute_act_, SIGNAL(triggered()), this, SLOT(execute()));
+
+ execute_original_act_ = new ElidedAction(this);
+ execute_original_act_->setEnabled(false);
+ connect(execute_original_act_, SIGNAL(triggered()), this, SLOT(executeOriginal()));
+
+ execute_protected_act_ = new ElidedAction("", this);
+ execute_protected_act_->setVisible(false);
+ connect(execute_protected_act_, SIGNAL(triggered()), this, SLOT(executeProtected()));
+
+ execute_parameters_act_ = new QWidgetAction(this);
+
+ search_act_ = new QAction(icon, QString::fromUtf8(language[lsSearch].c_str()), this);
+ search_act_->setShortcut(QString("Ctrl+F"));
+ search_act_->setEnabled(false);
+ connect(search_act_, SIGNAL(triggered()), this, SLOT(search()));
+
+ QList<QAction *> action_list = this->findChildren<QAction *>();
+ for (QList<QAction *>::ConstIterator it = action_list.constBegin(); it != action_list.constEnd(); it++) {
+ (*it)->setIconVisibleInMenu(false);
+ }
+
+ settings_act_ = new QAction(QString::fromUtf8(language[lsSettings].c_str()), this);
+ connect(settings_act_, SIGNAL(triggered()), this, SLOT(settings()));
+
+ // create menu
+ file_menu_ = menuBar()->addMenu(QString::fromUtf8(language[lsFile].c_str()));
+ file_menu_->addAction(open_act_);
+ file_menu_->addAction(save_act_);
+ file_menu_->addAction(save_as_act_);
+#ifdef ULTIMATE
+ file_menu_->addAction(save_licenses_act_);
+#endif
+ file_menu_->addAction(close_act_);
+ history_separator_ = file_menu_->addSeparator();
+ history_separator_->setVisible(false);
+ file_menu_->addSeparator();
+ file_menu_->addAction(exit_act_);
+
+ edit_menu_ = menuBar()->addMenu(QString::fromUtf8(language[lsEdit].c_str()));
+ edit_menu_->addAction(undo_act_);
+ edit_menu_->addAction(redo_act_);
+ edit_menu_->addSeparator();
+ edit_menu_->addAction(cut_act_);
+ edit_menu_->addAction(copy_act_);
+ edit_menu_->addAction(paste_act_);
+ edit_menu_->addAction(delete_act_);
+
+ edit_menu_->addSeparator();
+ edit_menu_->addAction(search_act_);
+#ifndef LITE
+ edit_menu_->addAction(goto_act_);
+#endif
+
+ project_menu_ = menuBar()->addMenu(QString::fromUtf8(language[lsProject].c_str()));
+#ifndef LITE
+ add_menu_ = project_menu_->addMenu(QString::fromUtf8(language[lsAdd].c_str()));
+ add_menu_->setEnabled(false);
+ add_menu_->addAction(add_function_act_);
+#endif
+#ifdef ULTIMATE
+ add_menu_->addAction(add_license_act_);
+ add_menu_->addAction(add_file_act_);
+#endif
+#ifndef LITE
+ add_menu_->addAction(add_folder_act_);
+#endif
+#ifdef ULTIMATE
+ project_menu_->addSeparator();
+ project_menu_->addAction(export_key_act_);
+ import_menu_ = project_menu_->addMenu(QString::fromUtf8(language[lsImport].c_str()));
+ import_menu_->setEnabled(false);
+ import_menu_->addAction(import_license_act_);
+ import_menu_->addAction(import_project_act_);
+#endif
+#ifndef LITE
+ project_menu_->addSeparator();
+#endif
+ project_menu_->addAction(compile_act_);
+ project_menu_->addAction(execute_act_);
+
+ tools_menu_ = menuBar()->addMenu(QString::fromUtf8(language[lsTools].c_str()));
+#ifndef LITE
+ tools_menu_->addAction(watermarks_act_);
+#endif
+ tools_menu_->addAction(settings_act_);
+
+ help_menu_ = menuBar()->addMenu(QString::fromUtf8(language[lsHelp].c_str()));
+ help_menu_->addAction(help_act_);
+ help_menu_->addSeparator();
+ help_menu_->addAction(home_page_act_);
+ help_menu_->addAction(about_act_);
+
+ function_ext_address_act_ = new QAction(QString::fromUtf8(language[lsExternalAddress].c_str()), this);
+ connect(function_ext_address_act_, SIGNAL(triggered()), this, SLOT(functionExtAddress()));
+ function_end_address_act_ = new QAction(QString::fromUtf8(language[lsBreakAddress].c_str()), this);
+ connect(function_end_address_act_, SIGNAL(triggered()), this, SLOT(functionEndAddress()));
+ function_del_act_ = new QAction(QString::fromUtf8(language[lsDelete].c_str()), this);
+ connect(function_del_act_, SIGNAL(triggered()), this, SLOT(functionDel()));
+
+ script_menu_ = new QMenu(this);
+ script_menu_->addAction(undo_act_);
+ script_menu_->addAction(redo_act_);
+ script_menu_->addSeparator();
+ script_menu_->addAction(cut_act_);
+ script_menu_->addAction(copy_act_);
+ script_menu_->addAction(paste_act_);
+ script_menu_->addAction(delete_act_);
+ script_menu_->addSeparator();
+ script_menu_->addAction(search_act_);
+
+ // create widgets
+ project_filter_ = new SearchLineEdit(this);
+ project_filter_->setFrame(false);
+ project_filter_->setFixedWidth(200);
+ connect(project_filter_, SIGNAL(textChanged(const QString &)), this, SLOT(projectFilterChanged()));
+ connect(project_filter_, SIGNAL(returnPressed()), this, SLOT(projectFilterChanged()));
+
+ QWidget *widget = new QWidget(this);
+ QLabel *label = new QLabel(QString::fromUtf8(language[lsParameters].c_str()) + ":", this);
+ parameters_edit_ = new LineEdit(this);
+ QBoxLayout *layout = new QHBoxLayout();
+ layout->setContentsMargins(16, 0, 0, 0);
+ layout->addWidget(label);
+ layout->addWidget(parameters_edit_);
+ widget->setLayout(layout);
+ execute_parameters_act_->setDefaultWidget(widget);
+
+ execute_menu_ = new QMenu(this);
+ execute_menu_->addAction(execute_original_act_);
+ execute_menu_->addAction(execute_protected_act_);
+ execute_menu_->addSeparator();
+ execute_menu_->addAction(execute_parameters_act_);
+
+ setContextMenuPolicy(Qt::NoContextMenu);
+
+ QToolBar *tool_bar = addToolBar("");
+ tool_bar->setMovable(false);
+ tool_bar->setIconSize(QSize(20, 20));
+ tool_bar->addSeparator();
+ tool_bar->addAction(open_act_);
+ tool_bar->addAction(save_act_);
+ tool_bar->addSeparator();
+ spacer_ = new ToolButtonElided(this);
+ spacer_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ spacer_->setCursor(Qt::PointingHandCursor);
+ spacer_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ spacer_->setFixedWidth(0);
+ connect(spacer_, SIGNAL(clicked()), this, SLOT(showFile()));
+ tool_bar->addWidget(spacer_);
+ tool_bar->addAction(compile_act_);
+ tool_bar->addAction(execute_act_);
+ QToolButton *button = reinterpret_cast<QToolButton *>(tool_bar->widgetForAction(execute_act_));
+ button->setMenu(execute_menu_);
+ button->setPopupMode(QToolButton::MenuButtonPopup);
+ project_separator_ = tool_bar->addSeparator();
+ //project_separator_->setVisible(false);
+ project_separator_widget_ = tool_bar->widgetForAction(project_separator_);
+ tool_bar->addAction(cut_act2_);
+ tool_bar->addAction(copy_act2_);
+ tool_bar->addAction(paste_act2_);
+#ifdef LITE
+ tool_bar->addAction(show_act_);
+ reinterpret_cast<QToolButton*>(tool_bar->widgetForAction(show_act_))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+#else
+ tool_bar->addAction(add_function_act2_);
+ reinterpret_cast<QToolButton*>(tool_bar->widgetForAction(add_function_act2_))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ tool_bar->addAction(goto_act2_);
+ reinterpret_cast<QToolButton*>(tool_bar->widgetForAction(goto_act2_))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+#endif
+#ifdef ULTIMATE
+ tool_bar->addAction(add_license_act2_);
+ reinterpret_cast<QToolButton*>(tool_bar->widgetForAction(add_license_act2_))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ tool_bar->addAction(add_file_act2_);
+ reinterpret_cast<QToolButton*>(tool_bar->widgetForAction(add_file_act2_))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+#endif
+
+ templates_save_act_ = new QAction(QString::fromUtf8(language[lsSaveTemplateAs].c_str()) + "...", this);
+ connect(templates_save_act_, SIGNAL(triggered()), this, SLOT(templatesSave()));
+
+ templates_edit_act_ = new QAction(QString::fromUtf8(language[lsEdit].c_str()) + "...", this);
+ connect(templates_edit_act_, SIGNAL(triggered()), this, SLOT(templatesEdit()));
+
+ templates_menu_ = new QMenu(this);
+ templates_menu_->addSeparator();
+ templates_menu_->addAction(templates_save_act_);
+ templates_menu_->addAction(templates_edit_act_);
+ connect(templates_menu_, SIGNAL(aboutToShow()), this, SLOT(templatesShow()));
+ updateTemplates();
+
+ templates_act_ = new QAction(copy_act_->icon(), QString::fromUtf8(language[lsTemplates].c_str()), this);
+ templates_act_->setVisible(false);
+
+ tool_bar->addAction(templates_act_);
+ QToolButton *template_button = reinterpret_cast<QToolButton*>(tool_bar->widgetForAction(templates_act_));
+ template_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ template_button->setPopupMode(QToolButton::InstantPopup);
+ template_button->setMenu(templates_menu_);
+
+ QWidget *spacer = new QWidget(this);
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ tool_bar->addWidget(spacer);
+ project_filter_act_ = tool_bar->addWidget(project_filter_);
+ project_filter_act_->setVisible(false);
+
+ project_frame_ = new QFrame(this);
+ status_bar_ = new QStatusBar(this);
+
+ project_tree_ = new TreeView(this);
+ project_tree_->setObjectName("project");
+ project_tree_->setFrameShape(QFrame::NoFrame);
+ project_tree_->header()->setObjectName("project");
+ project_tree_->setIconSize(QSize(18, 18));
+ project_tree_->setModel(project_model_);
+ project_tree_->setContextMenuPolicy(Qt::CustomContextMenu);
+ project_tree_->setDragDropMode(QAbstractItemView::DragDrop);
+ project_tree_->setItemDelegate(new ProjectTreeDelegate(this));
+ connect(project_tree_->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(projectItemChanged()));
+ connect(project_tree_, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(projectContextMenu(const QPoint &)));
+
+#ifndef LITE
+ functions_tree_ = new TreeView(this);
+ functions_tree_->setObjectName("project");
+ functions_tree_->setFrameShape(QFrame::NoFrame);
+ functions_tree_->header()->setObjectName("project");
+ functions_tree_->setIconSize(QSize(18, 18));
+ functions_tree_->setModel(functions_model_);
+ functions_tree_->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(functions_tree_->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(projectItemChanged()));
+ connect(functions_tree_, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(projectContextMenu(const QPoint &)));
+
+ info_tree_ = new TreeView(this);
+ info_tree_->setObjectName("project");
+ info_tree_->setFrameShape(QFrame::NoFrame);
+ info_tree_->header()->setObjectName("project");
+ info_tree_->setIconSize(QSize(18, 18));
+ info_tree_->setModel(info_model_);
+ connect(info_tree_->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(projectItemChanged()));
+#endif
+
+ project_tab_ = new TabWidget(this);
+ project_tab_->tabBar()->hide();
+ project_tab_->resize(240 * Application::stylesheetScaleFactor(), 10);
+
+ QFrame *tab_bar = new QFrame(this);
+ tab_bar->setObjectName("desktop");
+
+ icon_project_ = new QRadioButton(this);
+ icon_project_->setObjectName("project");
+ icon_project_->setChecked(true);
+ connect(icon_project_, SIGNAL(toggled(bool)), this, SLOT(projectTabClicked()));
+
+#ifndef LITE
+ icon_functions_ = new QRadioButton(this);
+ icon_functions_->setObjectName("functions");
+ connect(icon_functions_, SIGNAL(toggled(bool)), this, SLOT(projectTabClicked()));
+
+ icon_details_ = new QRadioButton(this);
+ icon_details_->setObjectName("details");
+ connect(icon_details_, SIGNAL(toggled(bool)), this, SLOT(projectTabClicked()));
+#endif
+
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(icon_project_);
+#ifndef LITE
+ layout->addWidget(icon_functions_);
+ layout->addWidget(icon_details_);
+#endif
+ layout->addStretch(1);
+ tab_bar->setLayout(layout);
+
+ project_tab_->addTab(project_tree_, "");
+#ifndef LITE
+ project_tab_->addTab(functions_tree_, "");
+ project_tab_->addTab(info_tree_, "");
+#endif
+ connect(project_tab_, SIGNAL(currentChanged(int)), this, SLOT(projectFilterChanged()));
+ connect(project_tab_, SIGNAL(resized()), this, SLOT(projectTabMoved()));
+
+ search_tree_ = new TreeView(this);
+ search_tree_->setObjectName("grid");
+ search_tree_->setIconSize(QSize(18, 18));
+ search_tree_->setRootIsDecorated(false);
+ search_tree_->setFrameShape(QFrame::NoFrame);
+ search_tree_->setModel(search_model_);
+ search_tree_->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ search_tree_->header()->setSectionsMovable(false);
+ connect(search_tree_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(treeItemDoubleClicked(QModelIndex)));
+
+ directory_tree_ = new TreeView(this);
+ directory_tree_->setObjectName("grid");
+ directory_tree_->setIconSize(QSize(18, 18));
+ directory_tree_->setFrameShape(QFrame::NoFrame);
+ directory_tree_->setRootIsDecorated(false);
+ directory_tree_->setModel(directory_model_);
+ directory_tree_->setItemDelegate(new ProjectTreeDelegate(this));
+ directory_tree_->header()->setSectionsMovable(false);
+ connect(directory_tree_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(treeItemDoubleClicked(QModelIndex)));
+ connect(directory_tree_->header(), SIGNAL(sectionClicked(int)), this, SLOT(treeSectionClicked(int)));
+ directory_tree_->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(directory_tree_, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(projectContextMenu(const QPoint &)));
+
+#ifndef LITE
+ dump_view_ = new TableView(this);
+ dump_view_->setObjectName("grid");
+ dump_view_->setIconSize(QSize(18, 18));
+ dump_view_->setFrameShape(QFrame::NoFrame);
+ dump_view_->setModel(dump_model_);
+ dump_view_->setShowGrid(false);
+ dump_view_->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ dump_view_->horizontalHeader()->resizeSection(0, 150 * Application::stylesheetScaleFactor());
+ dump_view_->horizontalHeader()->resizeSection(1, 300 * Application::stylesheetScaleFactor());
+ dump_view_->horizontalHeader()->setStretchLastSection(true);
+ dump_view_->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ dump_view_->horizontalHeader()->setSectionsClickable(false);
+ dump_view_->verticalHeader()->setDefaultSectionSize(dump_view_->verticalHeader()->minimumSectionSize());
+ dump_view_->setSelectionBehavior(QAbstractItemView::SelectRows);
+
+ disasm_view_ = new DisasmView(this);
+ disasm_view_->setObjectName("grid");
+ disasm_view_->setIconSize(QSize(18, 18));
+ disasm_view_->setFrameShape(QFrame::NoFrame);
+ disasm_view_->setModel(disasm_model_);
+ disasm_view_->setShowGrid(false);
+ disasm_view_->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ disasm_view_->horizontalHeader()->resizeSection(0, 150 * Application::stylesheetScaleFactor());
+ disasm_view_->horizontalHeader()->resizeSection(1, 300 * Application::stylesheetScaleFactor());
+ disasm_view_->horizontalHeader()->setStretchLastSection(true);
+ disasm_view_->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ disasm_view_->horizontalHeader()->setSectionsClickable(false);
+ disasm_view_->verticalHeader()->setDefaultSectionSize(dump_view_->verticalHeader()->minimumSectionSize());
+ disasm_view_->setSelectionBehavior(QAbstractItemView::SelectRows);
+ connect(disasm_view_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(disasmItemDoubleClicked(QModelIndex)));
+
+#endif
+
+ script_editor_ = new ScriptEdit(this);
+ script_editor_->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(script_editor_, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(scriptContextMenu(const QPoint &)));
+
+ project_file_name_ = new QLabel(this);
+
+ script_line_ = new QLabel(this);
+ script_line_->setFixedWidth(100);
+
+ script_column_ = new QLabel(this);
+ script_column_->setFixedWidth(100);
+
+ script_mode_ = new Label(this);
+ script_mode_->setFixedWidth(30);
+ connect(script_mode_, SIGNAL(doubleClicked()), this, SLOT(scriptModeClicked()));
+
+ status_bar_->addPermanentWidget(project_file_name_, 1);
+ status_bar_->addPermanentWidget(script_line_);
+ status_bar_->addPermanentWidget(script_column_);
+ status_bar_->addPermanentWidget(script_mode_);
+
+ core_property_editor_ = new TreePropertyEditor(this);
+ core_property_editor_->setModel(core_property_manager_);
+ core_property_editor_->expandToDepth(0);
+ core_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ core_property_editor_->header()->setSectionsMovable(false);
+
+ function_property_editor_ = new TreePropertyEditor(this);
+ function_property_editor_->setModel(function_property_manager_);
+ function_property_editor_->expandToDepth(0);
+ function_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ function_property_editor_->setContextMenuPolicy(Qt::CustomContextMenu);
+ function_property_editor_->setSelectionMode(QTreeView::ExtendedSelection);
+ function_property_editor_->header()->setSectionsMovable(false);
+ connect(function_property_editor_, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(functionContextMenu(const QPoint &)));
+ connect(function_property_editor_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(functionItemDoubleClicked(QModelIndex)));
+
+#ifndef LITE
+ section_property_editor_ = new TreePropertyEditor(this);
+ section_property_editor_->setModel(section_property_manager_);
+ section_property_editor_->expandToDepth(0);
+ section_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ section_property_editor_->header()->setSectionsMovable(false);
+
+ segment_property_editor_ = new TreePropertyEditor(this);
+ segment_property_editor_->setModel(segment_property_manager_);
+ segment_property_editor_->expandToDepth(0);
+ segment_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ segment_property_editor_->header()->setSectionsMovable(false);
+
+ import_property_editor_ = new TreePropertyEditor(this);
+ import_property_editor_->setModel(import_property_manager_);
+ import_property_editor_->expandToDepth(0);
+ import_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ import_property_editor_->header()->setSectionsMovable(false);
+
+ export_property_editor_ = new TreePropertyEditor(this);
+ export_property_editor_->setModel(export_property_manager_);
+ export_property_editor_->expandToDepth(0);
+ export_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ export_property_editor_->header()->setSectionsMovable(false);
+
+ resource_property_editor_ = new TreePropertyEditor(this);
+ resource_property_editor_->setModel(resource_property_manager_);
+ resource_property_editor_->expandToDepth(0);
+ resource_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ resource_property_editor_->header()->setSectionsMovable(false);
+
+ loadcommand_property_editor_ = new TreePropertyEditor(this);
+ loadcommand_property_editor_->setModel(loadcommand_property_manager_);
+ loadcommand_property_editor_->expandToDepth(0);
+ loadcommand_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ loadcommand_property_editor_->header()->setSectionsMovable(false);
+
+ address_calculator_ = new TreePropertyEditor(this);
+ address_calculator_->setModel(address_calculator_manager_);
+ address_calculator_->expandToDepth(0);
+ address_calculator_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ address_calculator_->header()->setSectionsMovable(false);
+#endif
+
+ QFont font;
+ font.setBold(true);
+
+#ifdef ULTIMATE
+ license_property_editor_ = new TreePropertyEditor(this);
+ license_property_editor_->setModel(license_property_manager_);
+ license_property_editor_->expandToDepth(0);
+ license_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ license_property_editor_->header()->setSectionsMovable(false);
+
+ internal_file_property_editor_ = new TreePropertyEditor(this);
+ internal_file_property_editor_->setModel(internal_file_property_manager_);
+ internal_file_property_editor_->expandToDepth(0);
+ internal_file_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ internal_file_property_editor_->header()->setSectionsMovable(false);
+
+ assembly_property_editor_ = new TreePropertyEditor(this);
+ assembly_property_editor_->setModel(assembly_property_manager_);
+ assembly_property_editor_->expandToDepth(0);
+ assembly_property_editor_->header()->resizeSection(0, 240 * Application::stylesheetScaleFactor());
+ assembly_property_editor_->header()->setSectionsMovable(false);
+
+ licensing_parameters_page_ = new QFrame(this);
+ licensing_parameters_page_->setObjectName("editor");
+
+ label = new QLabel(this);
+ label->setAlignment(Qt::AlignCenter);
+ label->setPixmap(QPixmap(":/images/key_gray.png"));
+
+ licensing_parameters_help_ = new QLabel(this);
+ licensing_parameters_help_->setObjectName("note");
+ licensing_parameters_help_->setAlignment(Qt::AlignCenter);
+ licensing_parameters_help_->setWordWrap(true);
+ licensing_parameters_help_->setText(QString::fromUtf8(language[lsKeyPairHelp].c_str()));
+
+ QFrame *key_frame = new QFrame(this);
+ key_frame->setObjectName("gridEditor");
+ key_frame->setFrameShape(QFrame::NoFrame);
+
+ key_algo_label_ = new QLabel(QString::fromUtf8(language[lsKeyPairAlgorithm].c_str()), this);
+ key_algo_label_->setObjectName("editor");
+
+ QComboBox *comboKeyAlgo = new QComboBox(this);
+ comboKeyAlgo->setFrame(false);
+ comboKeyAlgo->setFont(font);
+ comboKeyAlgo->addItem("RSA");
+ comboKeyAlgo->setCurrentIndex(0);
+
+ key_len_label_ = new QLabel(QString::fromUtf8(language[lsKeyLength].c_str()), this);
+ key_len_label_->setObjectName("editor");
+
+ key_len_ = new QComboBox(this);
+ key_len_->setFrame(false);
+ key_len_->setFont(font);
+ key_len_->addItems(QStringList() << "1024" << "1536" << "2048" << "2560" << "3072" << "3584" << "4096");
+ key_len_->setCurrentIndex(2);
+
+ create_key_button_ = new PushButton(QString::fromUtf8(language[lsGenerate].c_str()), this);
+ //create_key_button_->setDefault(true);
+ connect(create_key_button_, SIGNAL(clicked()), this, SLOT(createKeyPair()));
+
+ use_other_project_button_ = new PushButton(QString::fromUtf8(language[lsUseOtherProject].c_str()), this);
+ connect(use_other_project_button_, SIGNAL(clicked()), this, SLOT(useOtherProject()));
+
+ QGridLayout *keyLayout = new QGridLayout();
+ keyLayout->setContentsMargins(0, 1, 0, 1);
+ keyLayout->setHorizontalSpacing(0);
+ keyLayout->setVerticalSpacing(1);
+ keyLayout->addWidget(key_algo_label_, 0, 0);
+ keyLayout->addWidget(comboKeyAlgo, 0, 1);
+ keyLayout->addWidget(key_len_label_, 1, 0);
+ keyLayout->addWidget(key_len_, 1, 1);
+ key_frame->setLayout(keyLayout);
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->setContentsMargins(0, 0, 0, 0);
+ buttonLayout->setSpacing(10);
+ buttonLayout->addWidget(create_key_button_);
+ buttonLayout->addWidget(use_other_project_button_);
+ buttonLayout->setAlignment(Qt::AlignCenter);
+
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 50, 0, 0);
+ layout->setSpacing(30);
+ layout->addWidget(label);
+ layout->addWidget(licensing_parameters_help_);
+ layout->addWidget(key_frame);
+ layout->addLayout(buttonLayout);
+ layout->addStretch(1);
+ licensing_parameters_page_->setLayout(layout);
+#endif
+
+ QSplitter *splitter;
+#ifndef LITE
+ splitter = new QSplitter(this);
+ splitter->setOrientation(Qt::Vertical);
+ dump_page_ = new QFrame(this);
+ dump_page_->setObjectName("gridEditor");
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(disasm_view_);
+ layout->addWidget(splitter);
+ layout->addWidget(dump_view_);
+ dump_page_->setLayout(layout);
+
+ splitter->addWidget(disasm_view_);
+ splitter->addWidget(dump_view_);
+ splitter->setStretchFactor(0, 1);
+ splitter->setStretchFactor(1, 0);
+#endif
+
+ project_page_ = new QStackedWidget(this);
+ project_page_->addWidget(search_tree_);
+ project_page_->addWidget(directory_tree_);
+ project_page_->addWidget(function_property_editor_);
+ project_page_->addWidget(script_editor_);
+ project_page_->addWidget(core_property_editor_);
+#ifndef LITE
+ project_page_->addWidget(section_property_editor_);
+ project_page_->addWidget(segment_property_editor_);
+ project_page_->addWidget(import_property_editor_);
+ project_page_->addWidget(export_property_editor_);
+ project_page_->addWidget(resource_property_editor_);
+ project_page_->addWidget(loadcommand_property_editor_);
+ project_page_->addWidget(address_calculator_);
+ project_page_->addWidget(dump_page_);
+#endif
+#ifdef ULTIMATE
+ project_page_->addWidget(licensing_parameters_page_);
+ project_page_->addWidget(license_property_editor_);
+ project_page_->addWidget(internal_file_property_editor_);
+ project_page_->addWidget(assembly_property_editor_);
+#endif
+
+ context_find_ = new FindWidget(this);
+ context_find_->hide();
+ connect(context_find_, SIGNAL(findNext()), this, SLOT(contextFindNext()));
+ connect(context_find_, SIGNAL(findPrevious()), this, SLOT(contextFindPrevious()));
+ connect(context_find_, SIGNAL(find(QString, bool, bool)), this,
+ SLOT(contextFind(QString, bool, bool)));
+ connect(context_find_, SIGNAL(escapePressed()), this, SLOT(contextFindClosed()));
+
+ QWidget *project_find = new QWidget(this);
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(project_page_);
+ layout->addWidget(context_find_);
+ project_find->setLayout(layout);
+
+ log_tree_ = new LogTreeView(this);
+ log_tree_->setFrameShape(QFrame::NoFrame);
+ log_tree_->setRootIsDecorated(false);
+ log_tree_->setModel(log_model_);
+ connect(log_tree_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(logItemDoubleClicked(QModelIndex)));
+
+ splitter = new QSplitter(this);
+ splitter->setOrientation(Qt::Vertical);
+
+ QFrame *project_right = new QFrame(this);
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(project_find);
+ layout->addWidget(splitter);
+ layout->addWidget(log_tree_);
+ project_right->setLayout(layout);
+
+ splitter->addWidget(project_find);
+ splitter->addWidget(log_tree_);
+ splitter->setStretchFactor(0, 1);
+ splitter->setStretchFactor(1, 0);
+
+ splitter = new QSplitter(this);
+
+ QGridLayout *gridLayout = new QGridLayout();
+ gridLayout->setContentsMargins(0, 0, 0, 0);
+ gridLayout->setSpacing(0);
+ gridLayout->addWidget(tab_bar, 0, 0);
+ gridLayout->addWidget(project_tab_, 0, 1);
+ gridLayout->addWidget(splitter, 0, 2);
+ gridLayout->addWidget(project_right, 0, 3);
+ gridLayout->addWidget(status_bar_, 1, 0, 1, 4);
+ project_frame_->setLayout(gridLayout);
+
+ splitter->addWidget(project_tab_);
+ splitter->addWidget(project_right);
+ splitter->setStretchFactor(0, 0);
+ splitter->setStretchFactor(1, 1);
+
+ boot_frame_ = new QFrame(this);
+ boot_frame_->setObjectName("desktop");
+
+ boot_panel_ = new QFrame(this);
+ boot_panel_->setObjectName("boot");
+ boot_panel_->setMinimumSize(500, 300);
+
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(boot_panel_);
+ layout->setAlignment(boot_panel_, Qt::AlignCenter);
+ boot_frame_->setLayout(layout);
+
+ QFrame *top = new QFrame(this);
+ top->setObjectName("bootTop");
+
+ QLabel *logo = new QLabel(this);
+ logo->setPixmap(QPixmap(":/images/logo.png"));
+
+ welcome_label_ = new QLabel(QString::fromUtf8(language[lsWelcome].c_str()), this);
+ welcome_label_->setObjectName("version");
+
+ QLabel *version = new QLabel(QString::fromLatin1(Core::edition()) + " v " + QString::fromLatin1(Core::version()), this);
+ version->setObjectName("version");
+
+ QGridLayout *grid_layout = new QGridLayout();
+ grid_layout->setContentsMargins(30, 30, 30, 20);
+ grid_layout->setSpacing(0);
+ grid_layout->setColumnStretch(1, 1);
+ grid_layout->addWidget(logo, 0, 0, 2, 1);
+ grid_layout->addWidget(welcome_label_, 0, 1, Qt::AlignCenter);
+ grid_layout->addWidget(version, 1, 1, Qt::AlignCenter);
+ top->setLayout(grid_layout);
+
+ QFrame *line1 = new QFrame(this);
+ line1->setObjectName("bootHSeparator");
+ line1->setFixedHeight(1);
+
+ recent_files_label_ = new QLabel(QString::fromUtf8(language[lsRecentFiles].c_str()), this);
+ recent_files_label_->setObjectName("boot");
+
+ quick_start_label_ = new QLabel(QString::fromUtf8(language[lsQuickStart].c_str()), this);
+ quick_start_label_->setObjectName("boot");
+
+ QFrame *left = new QFrame(this);
+ left->setFixedWidth(boot_panel_->minimumSize().width() / 2);
+ recent_files_layout_ = new QVBoxLayout();
+ recent_files_layout_->setContentsMargins(10, 10, 10, 10);
+ recent_files_layout_->setSpacing(0);
+ recent_files_layout_->addWidget(recent_files_label_);
+ recent_files_layout_->addSpacing(10);
+ recent_files_layout_->addStretch(1);
+ left->setLayout(recent_files_layout_);
+
+ recent_file_open_act_ = new QAction(QString::fromUtf8(language[lsOpen].c_str()), this);
+ connect(recent_file_open_act_, SIGNAL(triggered()), this, SLOT(openRecentFile()));
+
+ recent_file_remove_act_ = new QAction(QString::fromUtf8(language[lsDelete].c_str()), this);
+ connect(recent_file_remove_act_, SIGNAL(triggered()), this, SLOT(removeRecentFile()));
+
+ recent_file_menu_ = new QMenu(this);
+ recent_file_menu_->addAction(recent_file_open_act_);
+ recent_file_menu_->addAction(recent_file_remove_act_);
+
+ open_button_ = new QToolButton(this);
+ open_button_->setObjectName("boot");
+ open_button_->setIconSize(QSize(24, 24));
+ open_button_->setIcon(QIcon(":/images/boot_open.png"));
+ open_button_->setText(QString::fromUtf8(language[lsOpen].c_str()) + "...");
+ open_button_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ open_button_->setAutoRaise(true);
+ open_button_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ connect(open_button_, SIGNAL(clicked(bool)), this, SLOT(open()));
+
+ examples_button_ = new QToolButton(this);
+ examples_button_->setObjectName("boot");
+ examples_button_->setIconSize(QSize(24, 24));
+ examples_button_->setIcon(QIcon(":/images/boot_examples.png"));
+ examples_button_->setText(QString::fromUtf8(language[lsExamples].c_str()) + "...");
+ examples_button_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ examples_button_->setAutoRaise(true);
+ examples_button_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ connect(examples_button_, SIGNAL(clicked(bool)), this, SLOT(examples()));
+
+ help_button_ = new QToolButton(this);
+ help_button_->setObjectName("boot");
+ help_button_->setIconSize(QSize(24, 24));
+ help_button_->setIcon(QIcon(":/images/boot_help.png"));
+ help_button_->setText(QString::fromUtf8(language[lsHelp].c_str()));
+ help_button_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ help_button_->setAutoRaise(true);
+ help_button_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ connect(help_button_, SIGNAL(clicked(bool)), this, SLOT(help()));
+
+ QFrame *right = new QFrame(this);
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(10, 10, 10, 10);
+ layout->setSpacing(0);
+ layout->addWidget(quick_start_label_);
+ layout->addSpacing(10);
+ layout->addWidget(open_button_);
+ layout->addWidget(examples_button_);
+ layout->addWidget(help_button_);
+ layout->addStretch(1);
+ right->setLayout(layout);
+
+ QFrame *line3 = new QFrame(this);
+ line3->setObjectName("bootVSeparator");
+ line3->setFixedWidth(1);
+
+ QFrame *center = new QFrame(this);
+ layout = new QHBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(left);
+ layout->addWidget(line3);
+ layout->addWidget(right);
+ center->setLayout(layout);
+
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(top);
+ layout->addWidget(line1);
+ layout->addWidget(center, 1);
+ boot_panel_->setLayout(layout);
+
+ desktop_page_ = new QStackedWidget(this);
+ desktop_page_->addWidget(boot_frame_);
+ desktop_page_->addWidget(project_frame_);
+ desktop_page_->setCurrentWidget(boot_frame_);
+ setCentralWidget(desktop_page_);
+
+ connect(QAbstractEventDispatcher::instance(), SIGNAL(awake()), SLOT(updateEditActions()));
+ connect(&fs_watcher_, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
+
+ setAcceptDrops(true);
+
+ std::vector<std::string> project_list = settings_file().project_list();
+ if (project_list.size() > 10)
+ project_list.resize(10);
+ for (int i = 0; i < (int)project_list.size(); i++) {
+ addRecentFile(i, QString::fromUtf8(project_list[i].c_str()));
+ }
+
+ localize();
+
+ QStringList args = QCoreApplication::arguments();
+ if (args.length() > 1) {
+ QString fileName(QFileInfo(args[1]).canonicalFilePath());
+ if (fileName.isEmpty()) // no file found -> will use original argument in error message
+ fileName = args[1];
+ loadFile(QDir::toNativeSeparators(fileName));
+ }
+}
+
+MainWindow::~MainWindow()
+{
+ delete core_;
+ delete log_;
+}
+
+void MainWindow::addRecentFile(int index, const QString file_name)
+{
+ history_separator_->setVisible(true);
+
+ QAction *action = new QAction(file_name, this);
+ connect(action, SIGNAL(triggered()), this, SLOT(loadFileFromHistory()));
+ int file_pos = file_menu_->actions().indexOf(history_separator_) + 1;
+ file_menu_->insertAction(file_menu_->actions().at(file_pos + index), action);
+
+ QFileInfo fileInfo(file_name);
+
+ QToolButton *button = new QToolButton(this);
+ button->setObjectName("boot");
+ button->setIconSize(QSize(16, 16));
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ button->setAutoRaise(true);
+ button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ button->setText(fileInfo.fileName());
+ button->setToolTip(file_name);
+ button->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(button, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(recentFileContextMenu(const QPoint &)));
+
+ QFileIconProvider ip;
+ QIcon icon = ip.icon(fileInfo);
+ if (icon.isNull())
+ icon = ip.icon(QFileIconProvider::File);
+ button->setIcon(icon);
+ connect(button, SIGNAL(clicked(bool)), this, SLOT(loadFileFromBoot()));
+
+ recent_files_layout_->insertWidget(2 + index, button);
+}
+
+void MainWindow::recentFileContextMenu(const QPoint &p)
+{
+ recent_file_ = -1;
+ QToolButton *widget = qobject_cast<QToolButton*>(sender());
+ if (widget) {
+ for (int i = 2; i < recent_files_layout_->count(); ++i) {
+ if (recent_files_layout_->itemAt(i)->widget() == widget) {
+ recent_file_ = i - 2;
+ break;
+ }
+ }
+ if (recent_file_ >= 0) {
+ widget->setDown(true);
+ recent_file_menu_->exec(qobject_cast<QWidget*>(sender())->mapToGlobal(p));
+ if (recent_file_ >= 0)
+ widget->setDown(false);
+ }
+ }
+}
+
+void MainWindow::openRecentFile()
+{
+ if (recent_file_ < 0)
+ return;
+
+ QToolButton *button = qobject_cast<QToolButton *>(recent_files_layout_->itemAt(2 + recent_file_)->widget());
+ if (button)
+ loadFile(button->toolTip());
+}
+
+void MainWindow::removeRecentFile()
+{
+ if (recent_file_ < 0)
+ return;
+
+ int file_pos = file_menu_->actions().indexOf(history_separator_) + 1;
+ QAction *action = file_menu_->actions().at(file_pos + recent_file_);
+ file_menu_->removeAction(action);
+ delete action;
+
+ QWidget *widget = recent_files_layout_->itemAt(2 + recent_file_)->widget();
+ recent_files_layout_->removeWidget(widget);
+ delete widget;
+
+ recent_file_ = -1;
+
+ saveRecentFiles();
+}
+
+void MainWindow::saveRecentFiles()
+{
+ std::vector<std::string> project_list;
+ int file_pos = file_menu_->actions().indexOf(history_separator_) + 1;
+ QList<QAction*> actions = file_menu_->actions();
+ for (int i = file_pos; i < actions.size() - 2; i++) {
+ QAction *action = actions[i];
+ project_list.push_back(action->text().toUtf8().constData());
+ }
+ settings_file().set_project_list(project_list);
+}
+
+void MainWindow::localize()
+{
+ file_menu_->setTitle(QString::fromUtf8(language[lsFile].c_str()));
+ open_act_->setText(QString::fromUtf8(language[lsOpen].c_str()) + "...");
+ save_act_->setText(QString::fromUtf8(language[lsSaveProject].c_str()));
+ save_as_act_->setText(QString::fromUtf8(language[lsSaveProjectAs].c_str()) + "...");
+ close_act_->setText(QString::fromUtf8(language[lsClose].c_str()));
+ exit_act_->setText(QString::fromUtf8(language[lsExit].c_str()));
+ project_filter_->setPlaceholderText(QString::fromUtf8(language[lsSearch].c_str()));
+
+ edit_menu_->setTitle(QString::fromUtf8(language[lsEdit].c_str()));
+ redo_act_->setText(QString::fromUtf8(language[lsRedo].c_str()));
+ undo_act_->setText(QString::fromUtf8(language[lsUndo].c_str()));
+ cut_act_->setText(QString::fromUtf8(language[lsCut].c_str()));
+ copy_act_->setText(QString::fromUtf8(language[lsCopy].c_str()));
+ paste_act_->setText(QString::fromUtf8(language[lsPaste].c_str()));
+ exclude_act_->setText(QString::fromUtf8(language[lsExcludedFromCompilation].c_str()));
+ block_act_->setText(QString::fromUtf8(language[lsBlocked].c_str()));
+ rename_act_->setText(QString::fromUtf8(language[lsRename].c_str()));
+ delete_act_->setText(QString::fromUtf8(language[lsDelete].c_str()));
+ cut_act2_->setText(cut_act_->text());
+ copy_act2_->setText(copy_act_->text());
+ paste_act2_->setText(paste_act_->text());
+ search_act_->setText(QString::fromUtf8(language[lsSearch].c_str()));
+
+ project_menu_->setTitle(QString::fromUtf8(language[lsProject].c_str()));
+#ifdef LITE
+ show_act_->setText(QString::fromUtf8(language[lsShowProtectedFunctions].c_str()));
+#else
+ add_menu_->setTitle(QString::fromUtf8(language[lsAdd].c_str()));
+ add_function_act_->setText(QString::fromUtf8(language[lsAddFunction].c_str()) + "...");
+ add_function_act2_->setText(add_function_act_->text());
+ add_folder_act_->setText(QString::fromUtf8(language[lsAddFolder].c_str()) + "...");
+ goto_act_->setText(QString::fromUtf8(language[lsGoTo].c_str()) + "...");
+ goto_act2_->setText(goto_act_->text());
+ templates_act_->setText(QString::fromUtf8(language[lsTemplates].c_str()));
+ templates_save_act_->setText(QString::fromUtf8(language[lsSaveTemplateAs].c_str()) + "...");
+ templates_edit_act_->setText(QString::fromUtf8(language[lsEdit].c_str()) + "...");
+ if (templates_menu_->actions().size() > 3)
+ templates_menu_->actions().at(0)->setText("(" + QString::fromUtf8(language[lsDefault].c_str()) + ")");
+#endif
+#ifdef ULTIMATE
+ save_licenses_act_->setText(QString::fromUtf8(language[lsSaveLicensesAs].c_str()) + "...");
+ add_license_act_->setText(QString::fromUtf8(language[lsAddLicense].c_str()) + "...");
+ add_file_act_->setText(QString::fromUtf8(language[lsAddFile].c_str()) + "...");
+ add_license_act2_->setText(add_license_act_->text());
+ add_file_act2_->setText(add_file_act_->text());
+ import_menu_->setTitle(QString::fromUtf8(language[lsImport].c_str()));
+ import_license_act_->setText(QString::fromUtf8(language[lsImportLicenseFromSerialNumber].c_str()) + "...");
+ import_project_act_->setText(QString::fromUtf8(language[lsImportLicensesFromProjectFile].c_str()) + "...");
+ export_key_act_->setText(QString::fromUtf8(language[lsExportKeyPair].c_str()) + "...");
+#endif
+ compile_act_->setText(QString::fromUtf8(language[lsCompile].c_str()));
+ execute_act_->setText(QString::fromUtf8(language[lsExecute].c_str()));
+
+ tools_menu_->setTitle(QString::fromUtf8(language[lsTools].c_str()));
+#ifndef LITE
+ watermarks_act_->setText(QString::fromUtf8(language[lsWatermarks].c_str()) + "...");
+#endif
+ settings_act_->setText(QString::fromUtf8(language[lsSettings].c_str()) + "...");
+
+ help_menu_->setTitle(QString::fromUtf8(language[lsHelp].c_str()));
+ help_act_->setText(QString::fromUtf8(language[lsContents].c_str()));
+ home_page_act_->setText(QString::fromUtf8(language[lsHomePage].c_str()));
+ about_act_->setText(QString::fromUtf8(language[lsAbout].c_str()) + "...");
+
+ icon_project_->setToolTip(QString::fromUtf8(language[lsProject].c_str()));
+#ifndef LITE
+ icon_functions_->setToolTip(QString::fromUtf8(language[lsFunctions].c_str()));
+ icon_details_->setToolTip(QString::fromUtf8(language[lsDetails].c_str()));
+#endif
+
+ function_end_address_act_->setText(QString::fromUtf8(language[lsBreakAddress].c_str()));
+ function_ext_address_act_->setText(QString::fromUtf8(language[lsExternalAddress].c_str()));
+ function_del_act_->setText(QString::fromUtf8(language[lsDelete].c_str()));
+
+#ifdef ULTIMATE
+ licensing_parameters_help_->setText(QString::fromUtf8(language[lsKeyPairHelp].c_str()));
+ key_algo_label_->setText(QString::fromUtf8(language[lsKeyPairAlgorithm].c_str()));
+ key_len_label_->setText(QString::fromUtf8(language[lsKeyLength].c_str()));
+ create_key_button_->setText(QString::fromUtf8(language[lsGenerate].c_str()));
+ use_other_project_button_->setText(QString::fromUtf8(language[lsUseOtherProject].c_str()));
+#endif
+
+ open_button_->setText(QString::fromUtf8(language[lsOpen].c_str()) + "...");
+ examples_button_->setText(QString::fromUtf8(language[lsExamples].c_str()) + "...");
+ help_button_->setText(QString::fromUtf8(language[lsHelp].c_str()));
+
+ recent_files_label_->setText(QString::fromUtf8(language[lsRecentFiles].c_str()));
+ recent_file_open_act_->setText(QString::fromUtf8(language[lsOpen].c_str()));
+ recent_file_remove_act_->setText(QString::fromUtf8(language[lsDelete].c_str()));
+
+ quick_start_label_->setText(QString::fromUtf8(language[lsQuickStart].c_str()));
+ welcome_label_->setText(QString::fromUtf8(language[lsWelcome].c_str()));
+
+ function_property_manager_->localize();
+ core_property_manager_->localize();
+ project_model_->localize();
+#ifndef LITE
+ info_model_->localize();
+ section_property_manager_->localize();
+ segment_property_manager_->localize();
+ import_property_manager_->localize();
+ export_property_manager_->localize();
+ resource_property_manager_->localize();
+ loadcommand_property_manager_->localize();
+ address_calculator_manager_->localize();
+#endif
+#ifdef ULTIMATE
+ license_property_manager_->localize();
+ internal_file_property_manager_->localize();
+ assembly_property_manager_->localize();
+#endif
+}
+
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasUrls())
+ event->acceptProposedAction();
+}
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+ if (!event->mimeData()->hasUrls())
+ return;
+
+ loadFile(QDir::toNativeSeparators(event->mimeData()->urls().at(0).toLocalFile()));
+}
+
+bool MainWindow::internalLoadFile(const QString &filename)
+{
+ bool res = false;
+ try {
+ res = core_->Open(filename.toUtf8().constData());
+ } catch(canceled_error &error) {
+ core_->Notify(mtWarning, NULL, error.what());
+ } catch(std::runtime_error &error) {
+ core_->Notify(mtError, NULL, error.what());
+ }
+ return res;
+}
+
+void MainWindow::loadFile(const QString &filename)
+{
+ if (!closeFile())
+ return;
+
+ boot_panel_->hide();
+ {
+ QFutureWatcher<bool> watcher;
+ ProgressDialog progress(this);
+ log_->reset();
+
+ connect(&watcher, SIGNAL(finished()), &progress, SLOT(reject()));
+ connect(&progress, SIGNAL(cancel()), log_, SLOT(cancel()));
+ connect(log_, SIGNAL(startProgress(const QString &, unsigned long long)), &progress, SLOT(startProgress(const QString &, unsigned long long)));
+ connect(log_, SIGNAL(stepProgress(unsigned long long)), &progress, SLOT(stepProgress(unsigned long long)));
+
+ watcher.setFuture(QtConcurrent::run(this, &MainWindow::internalLoadFile, filename));
+ progress.exec();
+ watcher.waitForFinished();
+ if (!watcher.result()) {
+ boot_panel_->show();
+ return;
+ }
+ }
+
+ if (core_->input_file())
+ fs_watcher_.addPath(QString::fromUtf8(core_->input_file()->file_name().c_str()));
+
+ QString input_file_name = QDir::toNativeSeparators(QDir::cleanPath(core_->input_file() ? QString::fromUtf8(core_->input_file()->file_name().c_str()) : filename));
+ QFileInfo fileInfo(input_file_name);
+ spacer_->setText(fileInfo.fileName());
+ spacer_->setToolTip(input_file_name);
+ QFileIconProvider ip;
+ QIcon icon = ip.icon(fileInfo);
+ if (icon.isNull())
+ icon = ip.icon(QFileIconProvider::File);
+ QPixmap pixmap = icon.pixmap(QSize(20, 20));
+ QImage image = pixmap.toImage();
+ for (int i = 0; i < pixmap.width(); ++i) {
+ for (int j = 0; j < pixmap.height(); ++j) {
+ QRgb col = image.pixel(i, j);
+ int gray = qGray(col);
+ image.setPixel(i, j, qRgba(gray, gray, gray, qAlpha(col)));
+ }
+ }
+ QIcon newIcon;
+ newIcon.addPixmap(pixmap, QIcon::Active, QIcon::Off);
+ newIcon.addPixmap(QPixmap::fromImage(image), QIcon::Normal, QIcon::Off);
+ spacer_->setIcon(newIcon);
+
+ IFile *file = core_->input_file();
+ if (file)
+ file->map_function_list()->ReadFromFile(*file);
+
+ bool is_found = false;
+ QList<QAction*> actions = file_menu_->actions();
+ int file_pos = actions.indexOf(history_separator_) + 1;
+ for (int i = file_pos; i < actions.size() - 2; i++) {
+ QAction *action = actions[i];
+ if (action->text() == filename) {
+ file_menu_->removeAction(action);
+ file_menu_->insertAction(file_menu_->actions().at(file_pos), action);
+
+ QWidget *button = recent_files_layout_->itemAt(2 + i - file_pos)->widget();
+ recent_files_layout_->removeWidget(button);
+ recent_files_layout_->insertWidget(2, button);
+ is_found = true;
+ break;
+ }
+ }
+ if (!is_found) {
+ addRecentFile(0, filename);
+
+ if (actions.size() - file_pos - 2 == 10) {
+ QAction *action = actions[9 + file_pos];
+ file_menu_->removeAction(action);
+ delete action;
+ }
+
+ if (recent_files_layout_->count() == 14) {
+ QWidget *widget = recent_files_layout_->itemAt(12)->widget();
+ recent_files_layout_->removeWidget(widget);
+ delete widget;
+ }
+ }
+
+ saveRecentFiles();
+
+ project_model_->setCore(core_);
+ ProjectNode *options = project_model_->indexToNode(project_model_->optionsIndex());
+ if (options)
+ options->setPropertyManager(core_property_manager_);
+ project_tree_->setCurrentIndex(project_model_->index(0, 0));
+
+#ifndef LITE
+ functions_model_->setCore(core_);
+ functions_tree_->setCurrentIndex(functions_model_->index(0, 0));
+
+ info_model_->setCore(core_);
+ info_tree_->setCurrentIndex(info_model_->index(0, 0));
+#endif
+
+ script_editor_->setText(QString(core_->script()->text().c_str()));
+ connect(script_editor_, SIGNAL(notify(SCNotification *)), this, SLOT(scriptNotify(SCNotification *)));
+ core_property_manager_->setCore(core_);
+
+ desktop_page_->setCurrentWidget(project_frame_);
+ icon_project_->setChecked(true);
+ project_tree_->setFocus();
+ project_filter_act_->setVisible(true);
+ save_as_act_->setEnabled(true);
+ close_act_->setEnabled(true);
+ search_act_->setEnabled(true);
+
+ bool file_loaded = core_->input_file() != NULL;
+ compile_act_->setEnabled(file_loaded);
+#ifndef LITE
+ icon_functions_->setVisible(file_loaded);
+ icon_details_->setVisible(file_loaded);
+ add_menu_->setEnabled(file_loaded);
+ add_function_act_->setEnabled(file_loaded);
+ add_folder_act_->setEnabled(file_loaded);
+ goto_act_->setEnabled(file_loaded);
+#endif
+
+ bool is_executable = core_->input_file() && core_->input_file()->is_executable();
+ execute_act_->setEnabled(is_executable);
+ execute_original_act_->setEnabled(is_executable);
+ execute_original_act_->setFullText(input_file_name);
+ execute_menu_->setDefaultAction(execute_original_act_);
+#ifdef ULTIMATE
+ add_file_act_->setEnabled(file_loaded && (core_->input_file()->disable_options() & cpVirtualFiles) == 0);
+ import_menu_->setEnabled(true);
+ import_project_act_->setEnabled(true);
+ updateLicensingActions();
+#endif
+ projectTabMoved();
+
+ updateCaption();
+}
+
+void MainWindow::loadFileFromHistory()
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ if (action)
+ loadFile(action->text());
+}
+
+void MainWindow::loadFileFromBoot()
+{
+ QToolButton *button = qobject_cast<QToolButton *>(sender());
+ if (button)
+ loadFile(button->toolTip());
+}
+
+bool MainWindow::closeFile()
+{
+ if (project_model_->isEmpty())
+ return true;
+
+ if (save_act_->isEnabled()) {
+ switch (MessageDialog::question(this, QString("%1 \"%2\"?").arg(QString::fromUtf8(language[lsSave].c_str())).arg(QString::fromUtf8(core_->project_file_name().c_str())), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Yes)) {
+ case QMessageBox::Yes:
+ if (!save())
+ return false;
+ break;
+ case QMessageBox::No:
+ // do nothing
+ break;
+ default:
+ return false;
+ }
+ }
+
+ fs_watcher_.removePaths(fs_watcher_.files());
+ fileChanged_ = false;
+
+ log_model_->clear();
+ project_model_->setCore(NULL);
+ directory_model_->setDirectory(NULL);
+ search_model_->clear();
+ disconnect(script_editor_, SIGNAL(notify(SCNotification *)), this, SLOT(scriptNotify(SCNotification *)));
+ script_editor_->setText("");
+ core_property_manager_->setCore(NULL);
+ function_property_manager_->setValue(NULL);
+#ifndef LITE
+ functions_model_->setCore(NULL);
+ info_model_->setCore(NULL);
+ disasm_model_->setFile(NULL);
+ dump_model_->setFile(NULL);
+ section_property_manager_->setValue(NULL);
+ segment_property_manager_->setValue(NULL);
+ import_property_manager_->setValue(NULL);
+ export_property_manager_->setValue(NULL);
+ resource_property_manager_->setValue(NULL);
+ loadcommand_property_manager_->setValue(NULL);
+ address_calculator_manager_->setValue(NULL);
+#endif
+#ifdef ULTIMATE
+ license_property_manager_->setValue(NULL);
+ internal_file_property_manager_->setValue(NULL);
+ assembly_property_manager_->setValue(NULL);
+#endif
+ if (temp_function_) {
+ for (size_t i = 0; i < temp_function_->count(); i++) {
+ delete temp_function_->item(i)->func();
+ }
+ delete temp_function_;
+ temp_function_ = NULL;
+ }
+ core_->Close();
+
+ spacer_->setFixedWidth(0);
+ spacer_->setText("");
+ spacer_->setToolTip("");
+ spacer_->setIcon(QIcon());
+ project_filter_act_->setVisible(false);
+ project_filter_->clear();
+ boot_panel_->show();
+ desktop_page_->setCurrentWidget(boot_frame_);
+ save_act_->setEnabled(false);
+ save_as_act_->setEnabled(false);
+ close_act_->setEnabled(false);
+ redo_act_->setEnabled(false);
+ undo_act_->setEnabled(false);
+ cut_act_->setEnabled(false);
+ copy_act_->setEnabled(false);
+ paste_act_->setEnabled(false);
+ block_act_->setEnabled(false);
+ exclude_act_->setEnabled(false);
+ rename_act_->setEnabled(false);
+ delete_act_->setEnabled(false);
+ search_act_->setEnabled(false);
+ //project_separator_->setVisible(false);
+ cut_act2_->setVisible(false);
+ copy_act2_->setVisible(false);
+ paste_act2_->setVisible(false);
+#ifdef LITE
+ show_act_->setVisible(false);
+#else
+ add_menu_->setEnabled(false);
+ add_function_act2_->setVisible(false);
+ goto_act_->setEnabled(false);
+ goto_act2_->setVisible(false);
+ add_function_act_->setEnabled(false);
+ add_folder_act_->setEnabled(false);
+#endif
+ templates_act_->setVisible(false);
+#ifdef ULTIMATE
+ save_licenses_act_->setEnabled(false);
+ add_license_act2_->setEnabled(false);
+ add_license_act2_->setVisible(false);
+ add_file_act2_->setVisible(false);
+ import_license_act_->setEnabled(false);
+ import_project_act_->setEnabled(false);
+ add_license_act_->setEnabled(false);
+ export_key_act_->setEnabled(false);
+ import_menu_->setEnabled(false);
+#endif
+ compile_act_->setEnabled(false);
+ execute_act_->setEnabled(false);
+ execute_protected_act_->setVisible(false);
+ updateCaption();
+
+ return true;
+}
+
+void MainWindow::open()
+{
+ QString fileName = FileDialog::getOpenFileName(this, QString::fromUtf8(language[lsOpen].c_str()), FileDialog::defaultPath(),
+ QString("%1 ("
+#ifdef VMP_GNU
+ "*.app *.dylib *.exe *.dll *.bpl *.ocx *.sys *.scr *.so);;%2 (*.vmp);;%3 (*)"
+#else
+ "*.exe *.dll *.bpl *.ocx *.sys *.scr *.dylib *.so);;%2 (*.vmp);;%3 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsExecutableFiles].c_str())).arg(QString::fromUtf8(language[lsProjectFiles].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+
+ if (fileName.isEmpty())
+ return;
+
+ loadFile(fileName);
+}
+
+bool MainWindow::save()
+{
+ bool ret = core_->Save();
+ if (ret) {
+ save_act_->setEnabled(false);
+ updateCaption();
+ } else {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsSaveFileError].c_str(), core_->project_file_name().c_str()).c_str()), QMessageBox::Ok);
+ }
+
+ return ret;
+}
+
+void MainWindow::saveAs()
+{
+ QString fileName = FileDialog::getSaveFileName(this, QString::fromUtf8(language[lsSave].c_str()), QString::fromUtf8(core_->project_file_name().c_str()),
+ QString(
+#ifdef VMP_GNU
+ "%1 (*.vmp);;%2 (*)"
+#else
+ "%1 (*.vmp);;%2 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsProjectFiles].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+
+ if (fileName.isEmpty())
+ return;
+
+ if (core_->SaveAs(fileName.toUtf8().constData())) {
+ save_act_->setEnabled(false);
+ updateCaption();
+ } else {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsSaveFileError].c_str(), fileName.toUtf8().constData()).c_str()), QMessageBox::Ok);
+ }
+}
+
+void MainWindow::saveLicenses()
+{
+#ifdef ULTIMATE
+ QString fileName = FileDialog::getSaveFileName(this, QString::fromUtf8(language[lsSave].c_str()), QString::fromUtf8(core_->project_file_name().c_str()),
+ QString(
+#ifdef VMP_GNU
+ "%1 (*.vmp);;%2 (*)"
+#else
+ "%1 (*.vmp);;%2 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsProjectFiles].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+
+ if (fileName.isEmpty())
+ return;
+
+ if (!core_->licensing_manager()->SaveAs(fileName.toUtf8().constData())) {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsSaveFileError].c_str(), fileName.toUtf8().constData()).c_str()), QMessageBox::Ok);
+ return;
+ }
+#endif
+}
+
+void MainWindow::homePage()
+{
+ QDesktopServices::openUrl(QUrl("http://www.vmpsoft.com"));
+}
+
+void MainWindow::help()
+{
+ QString keywordId;
+ ProjectNode *current = currentProjectNode();
+ if (current) {
+ switch (current->type()) {
+ case NODE_ROOT:
+ break;
+ case NODE_OPTIONS:
+ keywordId = "project::options";
+ break;
+ case NODE_SCRIPT:
+ case NODE_SCRIPT_BOOKMARK:
+ keywordId = "project::script";
+ break;
+ case NODE_FILES:
+ case NODE_FILE:
+ case NODE_FILE_FOLDER:
+ case NODE_ASSEMBLIES:
+ keywordId = "project::files";
+ break;
+ case NODE_LICENSES:
+ case NODE_LICENSE:
+ keywordId = "project::licenses";
+ break;
+ case NODE_FUNCTIONS:
+ case NODE_FUNCTION:
+ case NODE_FOLDER:
+ keywordId = "project::functions";
+ break;
+ case NODE_MAP_FUNCTION:
+ case NODE_MAP_FOLDER:
+ keywordId = "project::mapfunctions";
+ break;
+ default:
+ keywordId = "project::details";
+ break;
+ }
+ }
+ HelpBrowser::showTopic(keywordId);
+}
+
+void MainWindow::about()
+{
+ AboutDialog dialog(this);
+ dialog.exec();
+}
+
+void MainWindow::examples()
+{
+#ifdef VMP_GNU
+ QString path = QCoreApplication::applicationDirPath() + "/examples";
+#else
+ wchar_t buf[MAX_PATH];
+ QString path;
+ // ïðèîðèòåòíàÿ ïàïêà, ñþäà äèñòðèáóòèâ ïèøåò
+ if (SHGetSpecialFolderPathW(0, buf, CSIDL_COMMON_DOCUMENTS, FALSE))
+ {
+ path = QDir::fromNativeSeparators(QString::fromWCharArray(buf)) + "/VMProtect";
+ if (!QDir(path).exists())
+ path.clear();
+ }
+ if (path.isEmpty())
+ {
+ // åñëè íåñêîëüêî þçåðîâ ðàáîòàþò îäíîâðåìåííî, íàäî êàæäîìó ñêîïèðîâàòü ïàïêó èç CSIDL_COMMON_DOCUMENTS ê ñåáå â äîêóìåíòû,
+ // à èñõîäíóþ ãðîõíóòü - â èòîãå êàæäûé ðàáîòàåò ñî ñâîèì êàòàëîãîì
+ path = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first() + "/VMProtect";
+ }
+#endif
+
+ QString fileName = FileDialog::getOpenFileName(this, QString::fromUtf8(language[lsOpen].c_str()), path, QString("%1 ("
+#ifdef VMP_GNU
+ "*.app *.dylib *.exe *.dll *.bpl *.ocx *.sys *.scr *.so);;%2 (*.vmp);;%3 (*)"
+#else
+ "*.exe *.dll *.bpl *.ocx *.sys *.scr *.dylib *.so);;%2 (*.vmp);;%3 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsExecutableFiles].c_str())).arg(QString::fromUtf8(language[lsProjectFiles].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+
+ if (fileName.isEmpty())
+ return;
+
+ loadFile(fileName);
+}
+
+void MainWindow::watermarks()
+{
+#ifndef LITE
+ WatermarksWindow dialog(false, this);
+ dialog.exec();
+#endif
+}
+
+void MainWindow::showFile()
+{
+ QString path = spacer_->toolTip();
+#ifdef __APPLE__
+ QStringList scriptArgs;
+ scriptArgs << QLatin1String("-e")
+ << QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
+ .arg(path);
+ QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
+ scriptArgs.clear();
+ scriptArgs << QLatin1String("-e")
+ << QLatin1String("tell application \"Finder\" to activate");
+ QProcess::execute("/usr/bin/osascript", scriptArgs);
+#else
+#ifndef VMP_GNU
+ QString param;
+ if (!QFileInfo(path).isDir())
+ param = QLatin1String("/select,");
+ param += QDir::toNativeSeparators(path);
+ QProcess::startDetached("explorer " + param);
+#else
+ // we cannot select a file here, because no file browser really supports it...
+ const QString folder = QDir::toNativeSeparators(QFileInfo(path).absoluteDir().absolutePath());
+ QDesktopServices::openUrl(QUrl::fromLocalFile(folder));
+#endif
+#endif
+}
+
+void MainWindow::settings()
+{
+ std::string lang_id = settings_file().language();
+ SettingsDialog dialog(this);
+ if (dialog.exec() == QDialog::Accepted) {
+ if (settings_file().language() != lang_id)
+ localize();
+ }
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ if (closeFile())
+ event->accept();
+ else
+ event->ignore();
+}
+
+void MainWindow::projectModified()
+{
+ save_act_->setEnabled(true);
+ updateCaption();
+}
+
+void MainWindow::projectNodeRemoved(ProjectNode *node)
+{
+ directory_model_->removeNode(node);
+ search_model_->removeNode(node);
+}
+
+void MainWindow::projectObjectRemoved(void *object)
+{
+ if (function_property_manager_->value() && function_property_manager_->value() == object)
+ function_property_manager_->setValue(NULL);
+ log_model_->removeObject(object);
+}
+
+void MainWindow::updateCaption()
+{
+ QString caption = caption_;
+ if (!project_model_->isEmpty()) {
+ QString fileName = QString::fromUtf8(core_->project_file_name().c_str());
+ QFileInfo fileInfo(fileName);
+ caption = QString("%1%2 %3 %4").arg(fileInfo.fileName()).arg(save_act_->isEnabled() ? "*" : "").arg(QString::fromUtf8("\xE2\x80\x94")).arg(caption_);
+ project_file_name_->setText(fileName);
+ } else {
+ project_file_name_->setText("");
+ }
+ setWindowTitle(caption);
+}
+
+QTreeView *MainWindow::currentTreeView() const
+{
+#ifdef LITE
+ return project_tree_;
+#else
+ if (project_tab_->currentWidget() == project_tree_)
+ return project_tree_;
+ else if (project_tab_->currentWidget() == functions_tree_)
+ return functions_tree_;
+ else
+ return info_tree_;
+#endif
+}
+
+ProjectNode *MainWindow::currentProjectNode(bool focusedTree) const
+{
+ QTreeView *tree_view = (focusedTree && focusWidget() == directory_tree_ && directory_tree_->selectionModel()->selectedIndexes().count()) ? directory_tree_ : currentTreeView();
+ IProjectNodesModel *model = dynamic_cast<IProjectNodesModel *>(tree_view->model());
+ return model ? model->indexToNode(tree_view->currentIndex()) : NULL;
+}
+
+void MainWindow::projectItemChanged()
+{
+ if (project_filter_->text().isEmpty())
+ showCurrentObject();
+ else
+ project_filter_->clear();
+}
+
+void MainWindow::projectFilterChanged()
+{
+ if (project_filter_->text().isEmpty()) {
+ showCurrentObject();
+ return;
+ }
+
+ QAbstractItemModel *model = currentTreeView()->model();
+ assert(model);
+ if (model == NULL) return;
+
+ search_model_->search(reinterpret_cast<BaseModel *>(model)->root(), project_filter_->text()
+#ifdef LITE
+ , (show_act_->isVisible() && show_act_->isChecked())
+#endif
+ );
+ project_page_->setCurrentWidget(search_tree_);
+}
+
+void MainWindow::showCurrentObject()
+{
+ ProjectNode *current = currentProjectNode();
+ if (!current)
+ return;
+
+ cut_act2_->setVisible(current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK);
+ copy_act2_->setVisible(current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK);
+ paste_act2_->setVisible(current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK);
+ script_line_->setVisible(current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK);
+ script_column_->setVisible(current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK);
+ script_mode_->setVisible(current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK);
+ templates_act_->setVisible(current->type() == NODE_OPTIONS);
+#ifdef LITE
+ show_act_->setVisible(current->type() == NODE_FUNCTIONS || current->type() == NODE_MAP_FOLDER);
+#else
+ add_folder_act_->setEnabled(current->type() == NODE_FUNCTIONS || current->type() == NODE_FOLDER || current->type() == NODE_FUNCTION || current->type() == NODE_FILES || current->type() == NODE_FILE_FOLDER || current->type() == NODE_FILE || current->type() == NODE_ASSEMBLIES);
+ goto_act2_->setVisible(icon_details_->isChecked());
+#endif
+
+#ifdef LITE
+ if (show_act_->isVisible() && show_act_->isChecked()) {
+ ProjectNode *root = reinterpret_cast<BaseModel *>(currentTreeView()->model())->root();
+ search_model_->search(root, project_filter_->text(), true);
+ project_page_->setCurrentWidget(search_tree_);
+ context_find_->hide();
+ return;
+ }
+#endif
+
+ switch (current->type()) {
+#ifdef ULTIMATE
+ case NODE_LICENSES:
+ {
+ LicensingManager *licensingManager = static_cast<LicensingManager *>(current->data());
+ if (licensingManager->empty()) {
+ project_page_->setCurrentWidget(licensing_parameters_page_);
+ break;
+ }
+ }
+#endif
+ case NODE_ARCHITECTURE:
+ case NODE_LOAD_COMMANDS:
+ case NODE_SEGMENTS:
+ case NODE_FUNCTIONS:
+ case NODE_FOLDER:
+ case NODE_RESOURCES:
+ case NODE_RESOURCE_FOLDER:
+ case NODE_IMPORTS:
+ case NODE_IMPORT:
+ case NODE_EXPORTS:
+ case NODE_MAP_FOLDER:
+ case NODE_IMPORT_FOLDER:
+ case NODE_EXPORT_FOLDER:
+ case NODE_FILES:
+ case NODE_FILE_FOLDER:
+ case NODE_ASSEMBLIES:
+ directory_model_->setDirectory(current);
+ for (int i = 0; i < directory_tree_->header()->count(); i++) {
+ directory_tree_->header()->resizeSection(i, Application::stylesheetScaleFactor() *((i == 0) ? 240 : 100));
+ }
+
+ directory_tree_->header()->setSectionsClickable(current->type() == NODE_FUNCTIONS || current->type() == NODE_FOLDER || current->type() == NODE_FILES || current->type() == NODE_FILE_FOLDER || current->type() == NODE_LICENSES || current->type() == NODE_ASSEMBLIES);
+ project_page_->setCurrentWidget(directory_tree_);
+ break;
+
+ case NODE_OPTIONS:
+ project_page_->setCurrentWidget(core_property_editor_);
+ break;
+
+#ifndef LITE
+ case NODE_SCRIPT:
+ project_page_->setCurrentWidget(script_editor_);
+ break;
+
+ case NODE_SCRIPT_BOOKMARK:
+ project_page_->setCurrentWidget(script_editor_);
+ script_editor_->setFocus();
+ script_editor_->send(SCI_GOTOPOS, project_model_->bookmarkNodeToPos(current));
+ break;
+#endif
+
+ case NODE_MAP_FUNCTION:
+ {
+ MapFunctionBundle *map = static_cast<MapFunctionBundle *>(current->data());
+ FunctionBundle *func = core_->input_file()->function_list()->GetFunctionByName(map->name());
+ FunctionBundle *old_temp_function = NULL;
+ if (!func) {
+ old_temp_function = temp_function_;
+ temp_function_ = NULL;
+ func = new FunctionBundle(core_->input_file()->function_list(), map->full_name(), false);
+ for (size_t i = 0; i < map->count(); i++) {
+ MapFunctionArch *map_arch = map->item(i);
+ FunctionArch *func_arch = func->Add(map_arch->arch(), map_arch->arch()->function_list()->CreateFunction());
+ func_arch->func()->set_need_compile(false);
+ func_arch->func()->set_compilation_type(ctVirtualization);
+ func_arch->func()->ReadFromFile(*map_arch->arch(), map_arch->func()->address());
+ }
+ temp_function_ = func;
+ }
+ function_property_manager_->setValue(func);
+
+ if (old_temp_function) {
+ for (size_t i = 0; i < old_temp_function->count(); i++) {
+ delete old_temp_function->item(i)->func();
+ }
+ delete old_temp_function;
+ }
+ }
+ project_page_->setCurrentWidget(function_property_editor_);
+ break;
+
+ case NODE_FUNCTION:
+ {
+ FunctionBundle *object = static_cast<FunctionBundle *>(current->data());
+ function_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(function_property_editor_);
+ break;
+
+#ifndef LITE
+ case NODE_SEGMENT:
+ {
+ ISection *object = static_cast<ISection *>(current->data());
+ segment_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(segment_property_editor_);
+ break;
+
+ case NODE_SECTION:
+ {
+ ISection *object = static_cast<ISection *>(current->data());
+ section_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(section_property_editor_);
+ break;
+
+ case NODE_IMPORT_FUNCTION:
+ {
+ IImportFunction *object = static_cast<IImportFunction *>(current->data());
+ import_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(import_property_editor_);
+ break;
+
+ case NODE_EXPORT:
+ {
+ IExport *object = static_cast<IExport *>(current->data());
+ export_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(export_property_editor_);
+ break;
+
+ case NODE_RESOURCE:
+ {
+ IResource *object = static_cast<IResource *>(current->data());
+ resource_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(resource_property_editor_);
+ break;
+
+ case NODE_LOAD_COMMAND:
+ {
+ ILoadCommand *object = static_cast<ILoadCommand *>(current->data());
+ loadcommand_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(loadcommand_property_editor_);
+ break;
+
+ case NODE_CALC:
+ {
+ IArchitecture *file = static_cast<IArchitecture *>(current->data());
+ address_calculator_manager_->setValue(file);
+ }
+ project_page_->setCurrentWidget(address_calculator_);
+ break;
+
+ case NODE_DUMP:
+ {
+ IArchitecture *file = static_cast<IArchitecture *>(current->data());
+ QModelIndex index = disasm_view_->currentIndex();
+ disasm_model_->setFile(file);
+ if (!index.isValid() && file->entry_point())
+ goToDump(file, file->entry_point());
+ dump_model_->setFile(file);
+ }
+ project_page_->setCurrentWidget(dump_page_);
+ break;
+#endif
+
+#ifdef ULTIMATE
+ case NODE_LICENSE:
+ {
+ License *object = reinterpret_cast<License *>(current->data());
+ license_property_manager_->setValue(object);
+ }
+ project_page_->setCurrentWidget(license_property_editor_);
+ break;
+
+ case NODE_FILE:
+ if (project_model_->objectToNode(core_->file_manager()->folder_list())->type() == NODE_ASSEMBLIES) {
+ InternalFile *object = reinterpret_cast<InternalFile *>(current->data());
+ assembly_property_manager_->setValue(object);
+ project_page_->setCurrentWidget(assembly_property_editor_);
+ }
+ else {
+ InternalFile *object = reinterpret_cast<InternalFile *>(current->data());
+ internal_file_property_manager_->setValue(object);
+ project_page_->setCurrentWidget(internal_file_property_editor_);
+ }
+ break;
+#endif
+ }
+ if(!isContextSearchApplicable())
+ context_find_->hide();
+}
+
+void MainWindow::projectContextMenu(const QPoint &p)
+{
+ ProjectNode *current = currentProjectNode(true);
+ if (!current)
+ return;
+
+ QMenu menu;
+ switch (current->type()) {
+ case NODE_FUNCTIONS:
+ case NODE_FUNCTION:
+ case NODE_FOLDER:
+#ifndef LITE
+ menu.addAction(add_function_act2_);
+ menu.addAction(add_folder_act_);
+#endif
+ break;
+#ifdef ULTIMATE
+ case NODE_LICENSE:
+ {
+ License *object = reinterpret_cast<License *>(current->data());
+ block_act_->setChecked(object->blocked());
+ }
+ case NODE_LICENSES:
+ menu.addAction(add_license_act2_);
+ break;
+ case NODE_FILES:
+ case NODE_FILE_FOLDER:
+ case NODE_FILE:
+ case NODE_ASSEMBLIES:
+ menu.addAction(add_file_act2_);
+ menu.addAction(add_folder_act_);
+ break;
+#endif
+ }
+
+ switch (current->type()) {
+ case NODE_FUNCTION:
+ case NODE_FOLDER:
+ case NODE_LICENSE:
+ case NODE_FILE:
+ case NODE_FILE_FOLDER:
+ menu.addSeparator();
+ menu.addAction(delete_act_);
+ if (current->type() != NODE_FUNCTION)
+ menu.addAction(rename_act_);
+ break;
+ }
+
+ switch (current->type()) {
+ case NODE_LICENSE:
+ menu.addSeparator();
+ menu.addAction(block_act_);
+ break;
+ case NODE_FILES:
+ case NODE_ASSEMBLIES:
+#ifdef ULTIMATE
+ {
+ FileManager *object = static_cast<FileManager *>(current->data());
+ exclude_act_->setChecked(!object->need_compile());
+ }
+#endif
+ menu.addSeparator();
+ menu.addAction(exclude_act_);
+ break;
+ case NODE_FUNCTION:
+ {
+ FunctionBundle *object = static_cast<FunctionBundle *>(current->data());
+ exclude_act_->setChecked(!object->need_compile());
+ }
+ menu.addSeparator();
+ menu.addAction(exclude_act_);
+ break;
+ case NODE_SCRIPT:
+ case NODE_SCRIPT_BOOKMARK:
+ {
+ Script *object = static_cast<Script *>(current->data());
+ exclude_act_->setChecked(!object->need_compile());
+ }
+ menu.addAction(exclude_act_);
+ break;
+ case NODE_MAP_FUNCTION:
+ {
+ MapFunctionBundle *map = static_cast<MapFunctionBundle *>(current->data());
+ FunctionBundle *func = core_->input_file()->function_list()->GetFunctionByName(map->name());
+ exclude_act_->setChecked(func ? !func->need_compile() : true);
+ }
+ menu.addAction(exclude_act_);
+ break;
+ }
+
+ if (!menu.isEmpty())
+ {
+ rename_act_->setEnabled(current->type() == NODE_FOLDER || current->type() == NODE_LICENSE || current->type() == NODE_FILE_FOLDER || current->type() == NODE_FILE);
+ block_act_->setEnabled(current->type() == NODE_LICENSE);
+ exclude_act_->setEnabled(current->type() == NODE_FUNCTION || current->type() == NODE_SCRIPT_BOOKMARK || current->type() == NODE_SCRIPT || current->type() == NODE_FILES || current->type() == NODE_MAP_FUNCTION || current->type() == NODE_ASSEMBLIES);
+ menu.exec((qobject_cast<QAbstractScrollArea *>(QObject::sender()))->viewport()->mapToGlobal(p));
+ }
+}
+
+void MainWindow::scriptContextMenu(const QPoint &p)
+{
+ script_menu_->exec(script_editor_->viewport()->mapToGlobal(p));
+}
+
+void MainWindow::functionContextMenu(const QPoint &p)
+{
+ ICommand *command = function_property_manager_->indexToCommand(function_property_editor_->currentIndex());
+ if (command) {
+ QMenu menu;
+ menu.addAction(copy_act_);
+ menu.addSeparator();
+ menu.addAction(function_ext_address_act_);
+ menu.addAction(function_end_address_act_);
+ menu.exec(function_property_editor_->viewport()->mapToGlobal(p));
+ return;
+ }
+
+ IFunction *func = function_property_manager_->indexToFunction(function_property_editor_->currentIndex());
+ if (func) {
+ QMenu menu;
+ menu.addAction(function_del_act_);
+ menu.exec(function_property_editor_->viewport()->mapToGlobal(p));
+ return;
+ }
+}
+
+void MainWindow::functionExtAddress()
+{
+ ICommand *command = function_property_manager_->indexToCommand(function_property_editor_->currentIndex());
+ if (!command)
+ return;
+
+ ExtCommandList *extCommandList = command->owner()->ext_command_list();
+ ExtCommand *extCommand = extCommandList->GetCommandByAddress(command->address());
+ if (extCommand) {
+ delete extCommand;
+ } else {
+ extCommandList->Add(command->address());
+ }
+}
+
+void MainWindow::functionEndAddress()
+{
+ ICommand *command = function_property_manager_->indexToCommand(function_property_editor_->currentIndex());
+ if (!command)
+ return;
+
+ IFunction *func = command->owner();
+ func->set_break_address(func->is_breaked_address(command->address()) ? 0 : command->address());
+}
+
+void MainWindow::functionDel()
+{
+ IFunction *func = function_property_manager_->indexToFunction(function_property_editor_->currentIndex());
+ if (func)
+ delete func;
+}
+
+void MainWindow::treeItemDoubleClicked(const QModelIndex &index)
+{
+ ProjectNode *current = static_cast<ProjectNode *>(index.internalPointer());
+ if (!current)
+ return;
+
+ QString term;
+ if (project_page_->currentWidget() == search_tree_) {
+ term = project_filter_->text();
+ project_filter_->clear();
+ }
+
+ QTreeView *tree_view = currentTreeView();
+ BaseModel *model = reinterpret_cast<BaseModel*>(tree_view->model());
+ assert(model);
+ if (model == NULL) return;
+
+ if (current->type() == NODE_PROPERTY) {
+ Property *prop = static_cast<Property *>(current->data());
+ Property *root = prop;
+ while (root && root->parent()) {
+ root = root->parent();
+ }
+ if (core_property_manager_->root() == root) {
+ current = project_model_->indexToNode(project_model_->optionsIndex());
+ core_property_editor_->setCurrentIndex(core_property_manager_->propertyToIndex(prop));
+ }
+ }
+
+ tree_view->setCurrentIndex(reinterpret_cast<BaseModel*>(model)->nodeToIndex(current));
+
+ if (!term.isEmpty() && (current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK))
+ context_find_->showAndClear(term);
+}
+
+void MainWindow::notify(MessageType type, IObject *sender, const QString &message)
+{
+ if (sender) {
+ if (Watermark *watermark = dynamic_cast<Watermark *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ watermarks_model_->addWatermark(watermark);
+ break;
+ case mtChanged:
+ watermarks_model_->updateWatermark(watermark);
+ break;
+ case mtDeleted:
+ watermarks_model_->removeWatermark(watermark);
+ break;
+ }
+ return;
+ }
+ if (ProjectTemplate *pt = dynamic_cast<ProjectTemplate *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ templates_model_->addTemplate(pt);
+ break;
+ case mtChanged:
+ templates_model_->updateTemplate(pt);
+ break;
+ case mtDeleted:
+ templates_model_->removeTemplate(pt);
+ break;
+ }
+ updateTemplates();
+ return;
+ }
+ }
+
+ if (project_model_->isEmpty()) {
+ QApplication::restoreOverrideCursor();
+ switch (type) {
+ case mtError:
+ MessageDialog::critical(this, message, QMessageBox::Ok);
+ break;
+ case mtWarning:
+ MessageDialog::warning(this, message, QMessageBox::Ok);
+ break;
+ case mtInformation:
+ MessageDialog::information(this, message, QMessageBox::Ok);
+ break;
+ }
+ return;
+ }
+
+ QString add;
+ if (sender) {
+ if (dynamic_cast<Core *>(sender)) {
+ core_property_manager_->update();
+ projectModified();
+ } else if (IFunction *func = dynamic_cast<IFunction *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ project_model_->addFunction(func);
+#ifndef LITE
+ functions_model_->updateFunction(func);
+#endif
+ function_property_manager_->addFunction(func);
+ break;
+ case mtChanged:
+ if (temp_function_ && temp_function_->GetArchByFunction(func)) {
+ for (size_t i = 0; i < temp_function_->count(); i++) {
+ FunctionArch *func_arch = temp_function_->item(i);
+ IFunction *func_src = func_arch->func();
+ IFunction *func_dst = func_arch->arch()->function_list()->AddByAddress(func_src->address(), temp_function_->compilation_type(), temp_function_->compilation_options(), temp_function_->need_compile(), NULL);
+ if (func_dst) {
+ func_dst->set_break_address(func_src->break_address());
+ for (size_t i = 0; i < func_src->ext_command_list()->count(); i++) {
+ func_dst->ext_command_list()->Add(func_src->ext_command_list()->item(i)->address());
+ }
+ }
+ }
+ }
+ function_property_manager_->updateFunction(func);
+ project_model_->updateFunction(func);
+#ifndef LITE
+ functions_model_->updateFunction(func);
+#endif
+ break;
+ case mtDeleted:
+ {
+ bool needUpdate = function_property_manager_->removeFunction(func);
+ if (temp_function_) {
+ FunctionArch *func_arch = temp_function_->GetArchByFunction(func);
+ if (func_arch)
+ delete func_arch;
+ }
+ project_model_->removeFunction(func);
+ if (needUpdate)
+ function_property_manager_->update();
+#ifndef LITE
+ functions_model_->removeFunction(func);
+#endif
+ }
+ break;
+ default:
+ {
+ IArchitecture *arch = func->owner()->owner();
+ if (core_->input_file()->IndexOf(arch) == NOT_ID) {
+ sender = NULL;
+ arch = core_->input_file()->GetArchitectureByName(arch->name());
+ if (arch)
+ sender = (func->type() == otUnknown) ? arch->function_list()->GetUnknownByName(func->name()) : arch->function_list()->GetFunctionByAddress(func->address());
+ }
+ }
+ break;
+ }
+ } else if (Folder *folder = dynamic_cast<Folder *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ project_model_->addFolder(folder);
+ break;
+ case mtChanged:
+ project_model_->updateFolder(folder);
+ break;
+ case mtDeleted:
+ project_model_->removeFolder(folder);
+ break;
+ }
+ }
+#ifdef ULTIMATE
+ else if (License *license = dynamic_cast<License *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ project_model_->addLicense(license);
+ break;
+ case mtChanged:
+ project_model_->updateLicense(license);
+ if (license_property_manager_->value() == license)
+ license_property_manager_->update();
+ break;
+ case mtDeleted:
+ project_model_->removeLicense(license);
+ if (license_property_manager_->value() == license)
+ license_property_manager_->setValue(NULL);
+ break;
+ }
+ } else if (FileFolder *folder = dynamic_cast<FileFolder *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ project_model_->addFileFolder(folder);
+ break;
+ case mtChanged:
+ project_model_->updateFileFolder(folder);
+ break;
+ case mtDeleted:
+ project_model_->removeFileFolder(folder);
+ break;
+ }
+ } else if (InternalFile *file = dynamic_cast<InternalFile *>(sender)) {
+ switch (type) {
+ case mtAdded:
+ project_model_->addFile(file);
+ break;
+ case mtChanged:
+ project_model_->updateFile(file);
+ if (internal_file_property_manager_->value() == file)
+ internal_file_property_manager_->update();
+ else if (assembly_property_manager_->value() == file)
+ assembly_property_manager_->update();
+ break;
+ case mtDeleted:
+ project_model_->removeFile(file);
+ if (internal_file_property_manager_->value() == file)
+ internal_file_property_manager_->update();
+ else if (assembly_property_manager_->value() == file)
+ assembly_property_manager_->update();
+ break;
+ }
+ } else if (/*LicensingManager *licensingManager = */dynamic_cast<LicensingManager *>(sender)) {
+ if (type == mtChanged) {
+ updateLicensingActions();
+ core_property_manager_->update();
+ projectModified();
+ ProjectNode *current = currentProjectNode();
+ if (current && current->type() == NODE_LICENSES)
+ showCurrentObject();
+ }
+ } else if (dynamic_cast<FileManager *>(sender)) {
+ project_model_->updateFiles();
+ projectModified();
+ }
+#endif
+ else if (dynamic_cast<Script *>(sender)) {
+ if (type == mtChanged) {
+ project_model_->updateScript();
+ projectModified();
+ }
+ } else if (ExtCommand *extCommand = dynamic_cast<ExtCommand *>(sender)) {
+ if (!extCommand->owner())
+ return;
+
+ IFunction *func = extCommand->owner()->owner();
+ if (temp_function_ && temp_function_->GetArchByFunction(func))
+ notify(mtChanged, func, "");
+
+ project_model_->updateFunction(func);
+ if (function_property_manager_->value() && function_property_manager_->value()->GetArchByFunction(func))
+ function_property_manager_->update();
+ } else if (ICommand *command = dynamic_cast<ICommand *>(sender)) {
+ IFunction *func = command->owner();
+ IArchitecture *arch = func->owner()->owner();
+
+ std::string func_name = func->display_name();
+ if (!func_name.empty())
+ func_name += ".";
+ add = QString::fromUtf8(string_format("%s%.8llX: ", func_name.c_str(), command->address()).c_str());
+ if (core_->input_file()->IndexOf(arch) == NOT_ID) {
+ sender = NULL;
+ arch = core_->input_file()->GetArchitectureByName(arch->name());
+ if (arch)
+ sender = (func->type() == otUnknown) ? arch->function_list()->GetFunctionByName(func->name()) : arch->function_list()->GetFunctionByAddress(func->address());
+ } else {
+ sender = func;
+ }
+ }
+#ifndef LITE
+ else if (IResource *resource = dynamic_cast<IResource *>(sender)) {
+ switch (type) {
+ case mtChanged:
+ info_model_->updateResource(resource);
+ if (resource_property_manager_->value() == resource)
+ resource_property_manager_->update();
+ break;
+ }
+ } else if (ISection *section = dynamic_cast<ISection *>(sender)) {
+ switch (type) {
+ case mtChanged:
+ info_model_->updateSegment(section);
+ if (segment_property_manager_->value() == section)
+ segment_property_manager_->update();
+ break;
+ }
+ } else if (IImport *import = dynamic_cast<IImport *>(sender)) {
+ switch (type) {
+ case mtChanged:
+ info_model_->updateImport(import);
+ break;
+ }
+ }
+#endif
+ }
+
+ if (type == mtInformation || type == mtWarning || type == mtError || type == mtScript)
+ log_model_->addMessage(type, sender, add + message);
+}
+
+void MainWindow::projectTabClicked()
+{
+#ifdef LITE
+ icon_project_->setChecked(true);
+#else
+ if (icon_details_->isChecked())
+ project_tab_->setCurrentWidget(info_tree_);
+ else if (icon_functions_->isChecked())
+ project_tab_->setCurrentWidget(functions_tree_);
+ else
+#endif
+ project_tab_->setCurrentWidget(project_tree_);
+}
+
+void MainWindow::projectTabMoved()
+{
+ spacer_->setFixedWidth((spacer_->width() > project_separator_widget_->pos().x() ? 0 : spacer_->width()) + project_tab_->width() + icon_project_->width() - project_separator_widget_->pos().x());
+}
+
+void MainWindow::scriptNotify(SCNotification *notification)
+{
+ switch (notification->nmhdr.code) {
+ case SCN_MODIFIED:
+ if (notification->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) {
+ core_->script()->set_text(script_editor_->text().toUtf8().constData());
+ projectModified();
+#ifndef LITE
+ project_model_->updateScriptBookmarks();
+#endif
+ }
+ break;
+
+ case SCN_UPDATEUI:
+ undo_act_->setEnabled(script_editor_->canUndo());
+ redo_act_->setEnabled(script_editor_->canRedo());
+ cut_act_->setEnabled(script_editor_->hasSelection());
+ copy_act_->setEnabled(script_editor_->hasSelection());
+ paste_act_->setEnabled(script_editor_->canPaste());
+
+ cut_act2_->setEnabled(cut_act_->isEnabled());
+ copy_act2_->setEnabled(copy_act_->isEnabled());
+ paste_act2_->setEnabled(paste_act_->isEnabled());
+
+ script_line_->setText(QString("Ln: %1").arg(script_editor_->currentPos().y() + 1));
+ script_column_->setText(QString("Col: %2").arg(script_editor_->currentPos().x() + 1));
+ script_mode_->setText(script_editor_->getOverType() ? "OVR" : "INS");
+
+ script_editor_->hilightView();
+ break;
+
+ case SCN_CHARADDED:
+ script_editor_->maintainIndentation(notification->ch);
+ break;
+ }
+}
+
+void MainWindow::scriptModeClicked()
+{
+ script_editor_->setOverType(!script_editor_->getOverType());
+ script_mode_->setText(script_editor_->getOverType() ? "OVR" : "INS");
+}
+
+void MainWindow::undo()
+{
+ QWidget *widget = focusWidget();
+ if (widget == script_editor_)
+ script_editor_->undo();
+ else if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget))
+ edit->undo();
+ else if (QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(widget))
+ edit->undo();
+ else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget))
+ comboBox->lineEdit()->undo();
+}
+
+void MainWindow::redo()
+{
+ QWidget *widget = focusWidget();
+ if (widget == script_editor_)
+ script_editor_->redo();
+ else if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget))
+ edit->redo();
+ else if (QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(widget))
+ edit->redo();
+ else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget))
+ comboBox->lineEdit()->redo();
+}
+
+void MainWindow::copy()
+{
+ QWidget *widget = focusWidget();
+ if (widget == script_editor_)
+ script_editor_->copy();
+ else if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget))
+ edit->copy();
+ else if (QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(widget))
+ edit->copy();
+ else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget))
+ comboBox->lineEdit()->copy();
+#ifdef ULTIMATE
+ else if (widget == license_property_editor_ && license_property_manager_->indexToProperty(license_property_editor_->currentIndex()) == license_property_manager_->serialNumber())
+ QApplication::clipboard()->setText(license_property_manager_->serialNumber()->value());
+#endif
+ else if (TreeView *tree = dynamic_cast<TreeView *>(widget))
+ tree->copy();
+ else if (TableView *table = dynamic_cast<TableView *>(widget))
+ table->copy();
+}
+
+void MainWindow::cut()
+{
+ QWidget *widget = focusWidget();
+ if (widget == script_editor_)
+ script_editor_->cut();
+ else if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget))
+ edit->cut();
+ else if (QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(widget))
+ edit->cut();
+ else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget))
+ comboBox->lineEdit()->cut();
+}
+
+void MainWindow::paste()
+{
+ QWidget *widget = focusWidget();
+ if (widget == script_editor_)
+ script_editor_->paste();
+ else if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget))
+ edit->paste();
+ else if (QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(widget))
+ edit->paste();
+ else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget))
+ comboBox->lineEdit()->paste();
+}
+
+void MainWindow::addFunction()
+{
+ FunctionDialog dialog(core_->input_file(), NULL, smAddFunction, this);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ QList<AddressInfo> addresses = dialog.addresses();
+ CompilationType compilationType = dialog.compilationType();
+ uint32_t compilationOptions = dialog.compilationOptions();
+ if (addresses.isEmpty())
+ return;
+
+ ProjectNode *node = currentProjectNode();
+ assert(node);
+ if (node == NULL) return;
+
+ while (node->type() == NODE_FUNCTION) {
+ node = node->parent();
+ }
+ Folder *folder = (node->type() == NODE_FOLDER) ? reinterpret_cast<Folder *>(node->data()) : NULL;
+
+ WaitCursor wc;
+ /*
+ if (addresses.size() > 1)
+ ProgressDialog::Start((language[lsLoading] + "...").c_str(), addresses.size());
+
+
+ IFile *file = core_->input_file();*/
+ IFunction *func = NULL;
+ for (int i = 0; i < addresses.size(); i++) {
+ //ProgressDialog::Step(1);
+ AddressInfo info = addresses[i];
+ IFunction *tmp = info.arch->function_list()->AddByAddress(info.address, compilationType, compilationOptions, true, folder);
+ if (!func)
+ func = tmp;
+ }
+ //ProgressDialog::End();
+
+ if (func)
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(func));
+ }
+}
+
+void MainWindow::addFolder()
+{
+ ProjectNode *node = currentProjectNode();
+ assert(node);
+ if (node == NULL) return;
+
+ switch (node->type()) {
+ case NODE_FUNCTIONS:
+ case NODE_FOLDER:
+ case NODE_FUNCTION:
+ addFunctionFolder();
+ break;
+ case NODE_FILES:
+ case NODE_FILE_FOLDER:
+ case NODE_FILE:
+ case NODE_ASSEMBLIES:
+ addFileFolder();
+ break;
+ }
+}
+
+void MainWindow::addFunctionFolder()
+{
+ ProjectNode *node = currentProjectNode();
+ assert(node);
+ if (node == NULL) return;
+
+ while (node->type() == NODE_FUNCTION) {
+ node = node->parent();
+ }
+
+ Folder *parent = (node->type() == NODE_FOLDER) ? reinterpret_cast<Folder *>(node->data()) : core_->input_file()->folder_list();
+
+ QModelIndex index = project_model_->objectToIndex(parent->Add(""));
+ project_tree_->setCurrentIndex(index);
+ project_tree_->edit(index);
+}
+
+#ifdef ULTIMATE
+void MainWindow::updateLicensingActions()
+{
+ bool is_ok = !core_->licensing_manager()->empty();
+ save_licenses_act_->setEnabled(is_ok);
+ export_key_act_->setEnabled(is_ok);
+ import_license_act_->setEnabled(is_ok);
+ add_license_act_->setEnabled(is_ok);
+ add_license_act2_->setEnabled(is_ok);
+}
+
+void MainWindow::createLicense(License *license)
+{
+ LicenseDialog dialog(core_->licensing_manager(), license, this);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ license = dialog.license();
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(license));
+ }
+}
+#endif
+
+void MainWindow::addLicense()
+{
+#ifdef ULTIMATE
+ createLicense(NULL);
+#endif
+}
+
+void MainWindow::createKeyPair()
+{
+#ifdef ULTIMATE
+ WaitCursor wc;
+ core_->licensing_manager()->Init(key_len_->currentText().toInt());
+#endif
+}
+
+void MainWindow::exportKeyPair()
+{
+#ifdef ULTIMATE
+ ExportKeyPairDialog dialog(this, core_->licensing_manager());
+
+ dialog.exec();
+#endif
+}
+
+void MainWindow::useOtherProject()
+{
+#ifdef ULTIMATE
+ QString fileName = FileDialog::getOpenFileName(this, QString::fromUtf8(language[lsOpen].c_str()), FileDialog::defaultPath(),
+ QString(
+#ifdef VMP_GNU
+ "%1 (*.vmp);;%2 (*)"
+#else
+ "%1 (*.vmp);;%2 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsProjectFiles].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+
+ if (fileName.isEmpty())
+ return;
+
+ LicensingManager manager;
+ if (!manager.Open(fileName.toUtf8().constData())) {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsOpenFileError].c_str(), fileName.toUtf8().constData()).c_str()), QMessageBox::Ok);
+ return;
+ }
+
+ if (manager.algorithm() != alRSA) {
+ MessageDialog::critical(this, QString("The license data not found in the file \"%1\"").arg(fileName), QMessageBox::Ok);
+ return;
+ }
+
+ core_->set_license_data_file_name(fileName.toUtf8().constData());
+#endif
+}
+
+void MainWindow::importLicense()
+{
+#ifdef ULTIMATE
+ ImportLicenseDialog dialog(this);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ std::string serialNumber = dialog.serial().toLatin1().constData();
+ LicensingManager *licensingManager = core_->licensing_manager();
+ License *license = licensingManager->GetLicenseBySerialNumber(serialNumber);
+ if (!license) {
+ LicenseInfo licenseInfo;
+ if (!licensingManager->DecryptSerialNumber(serialNumber, licenseInfo)) {
+ MessageDialog::critical(this, QString::fromUtf8(language[lsImportSerialNumberError].c_str()), QMessageBox::Ok);
+ return;
+ }
+ QDate date = QDate::currentDate();
+ license = licensingManager->Add(LicenseDate(date.year(), date.month(), date.day()),
+ licenseInfo.CustomerName,
+ licenseInfo.CustomerEmail,
+ "",
+ "",
+ serialNumber,
+ false);
+ }
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(license));
+ }
+#endif
+}
+
+void MainWindow::importProject()
+{
+#ifdef ULTIMATE
+ QString fileName = FileDialog::getOpenFileName(this, QString::fromUtf8(language[lsOpen].c_str()), FileDialog::defaultPath(),
+ QString(
+#ifdef VMP_GNU
+ "%1 (*.vmp);;%2 (*)"
+#else
+ "%1 (*.vmp);;%2 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsProjectFiles].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+ if (fileName.isEmpty())
+ return;
+
+ LicensingManager manager;
+ if (!manager.Open(fileName.toUtf8().constData())) {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsOpenFileError].c_str(), fileName.toUtf8().constData()).c_str()), QMessageBox::Ok);
+ return;
+ }
+
+ if (manager.algorithm() != alRSA) {
+ MessageDialog::critical(this, QString("The licensing parameters are not found in the file \"%1\"").arg(fileName), QMessageBox::Ok);
+ return;
+ }
+
+ if (!core_->licensing_manager()->CompareParameters(manager)) {
+ MessageDialog::critical(this, QString::fromUtf8(language[lsImportLicensesError].c_str()), QMessageBox::Ok);
+ return;
+ }
+
+ size_t c = 0;
+ size_t b = 0;
+ for (size_t i = 0; i < manager.count(); i++) {
+ License *src_license = manager.item(i);
+ License *dst_license = core_->licensing_manager()->GetLicenseBySerialNumber(src_license->serial_number());
+ if (dst_license) {
+ if (!dst_license->blocked() && src_license->blocked()) {
+ dst_license->set_blocked(src_license->blocked());
+ b++;
+ }
+ } else {
+ /*dst_license =*/ core_->licensing_manager()->Add(src_license->date(),
+ src_license->customer_name(),
+ src_license->customer_email(),
+ src_license->order_ref(),
+ src_license->comments(),
+ src_license->serial_number(),
+ src_license->blocked());
+ c++;
+ }
+ }
+ MessageDialog::information(this, QString::fromUtf8(string_format(language[lsImportLicensesResult].c_str(), c, b).c_str()), QMessageBox::Ok);
+#endif
+}
+
+void MainWindow::addFileFolder()
+{
+#ifdef ULTIMATE
+ ProjectNode *node = currentProjectNode();
+ assert(node);
+ if (node == NULL) return;
+
+ while (node->type() == NODE_FILE) {
+ node = node->parent();
+ }
+
+ FileFolder *parent = (node->type() == NODE_FILE_FOLDER) ? reinterpret_cast<FileFolder *>(node->data()) : core_->file_manager()->folder_list();
+
+ QModelIndex index = project_model_->objectToIndex(parent->Add(""));
+ project_tree_->setCurrentIndex(index);
+ project_tree_->edit(index);
+#endif
+}
+
+void MainWindow::addFile()
+{
+#ifdef ULTIMATE
+ QString filter;
+ if (project_model_->objectToNode(core_->file_manager()->folder_list())->type() == NODE_ASSEMBLIES) {
+ filter = QString(
+ "%1 (*.dll);;%2 (*.*)"
+ ).arg(QString::fromUtf8(language[lsAssemblies].c_str())).arg(QString::fromUtf8(language[lsAllFiles].c_str()));
+ }
+ else {
+ filter = QString(
+#ifdef VMP_GNU
+ "%1 (*)"
+#else
+ "%1 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsAllFiles].c_str()));
+ }
+
+ QString fileName = FileDialog::getOpenFileName(this, QString::fromUtf8(language[lsOpen].c_str()), FileDialog::defaultPath(), filter);
+ if (fileName.isEmpty())
+ return;
+
+ QString tmp = QDir(QString::fromUtf8(core_->project_path().c_str())).relativeFilePath(fileName);
+ if (tmp.mid(0, 2) != "..")
+ fileName = tmp;
+
+ ProjectNode *node = currentProjectNode();
+ while (node->type() == NODE_FILE) {
+ node = node->parent();
+ }
+ FileFolder *folder = (node->type() == NODE_FILE_FOLDER) ? reinterpret_cast<FileFolder *>(node->data()) : NULL;
+
+ FileManager *file_manager = core_->file_manager();
+ InternalFile *file = file_manager->Add(QFileInfo(fileName).fileName().toUtf8().constData(), fileName.toUtf8().constData(), faNone, folder);
+ if (file)
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(file));
+#endif
+}
+
+void MainWindow::rename()
+{
+ QTreeView *tree_view = qobject_cast<QTreeView *>(focusWidget());
+ if (tree_view)
+ tree_view->edit(tree_view->currentIndex());
+}
+
+void MainWindow::excludeFromCompilation()
+{
+ ProjectNode *node = currentProjectNode(true);
+ if (!node)
+ return;
+
+ switch (node->type()) {
+ case NODE_FUNCTION:
+ {
+ FunctionBundle *object = reinterpret_cast<FunctionBundle *>(node->data());
+ object->set_need_compile(!object->need_compile());
+ }
+ break;
+ case NODE_SCRIPT:
+ case NODE_SCRIPT_BOOKMARK:
+ {
+ Script *object = reinterpret_cast<Script *>(node->data());
+ object->set_need_compile(!object->need_compile());
+ }
+ break;
+#ifdef ULTIMATE
+ case NODE_FILES:
+ case NODE_ASSEMBLIES:
+ {
+ FileManager *object = reinterpret_cast<FileManager *>(node->data());
+ object->set_need_compile(!object->need_compile());
+ }
+ break;
+#endif
+ case NODE_MAP_FUNCTION:
+ {
+ MapFunctionBundle *object = static_cast<MapFunctionBundle *>(node->data());
+ FunctionBundle *func = core_->input_file()->function_list()->GetFunctionByName(object->name());
+ if (func) {
+ func->set_need_compile(!func->need_compile());
+ } else {
+ for (size_t i = 0; i < object->count(); i++) {
+ MapFunctionArch *map_arch = object->item(i);
+ map_arch->arch()->function_list()->AddByAddress(map_arch->func()->address(), ctVirtualization, 0, true, NULL);
+ }
+ }
+ }
+ break;
+ }
+}
+
+void MainWindow::block()
+{
+#ifdef ULTIMATE
+ ProjectNode *node = currentProjectNode(true);
+ if (!node)
+ return;
+
+ switch (node->type()) {
+ case NODE_LICENSE:
+ {
+ License *license = reinterpret_cast<License *>(node->data());
+ license->set_blocked(!license->blocked());
+ }
+ break;
+ }
+#endif
+}
+
+void MainWindow::del()
+{
+ ProjectNode *node = currentProjectNode(true);
+ if (!node)
+ return;
+
+ switch (node->type()) {
+ case NODE_SCRIPT:
+ case NODE_SCRIPT_BOOKMARK:
+ script_editor_->del();
+ break;
+ case NODE_FOLDER:
+ {
+ Folder *folder = reinterpret_cast<Folder *>(node->data());
+ if (MessageDialog::question(this, QString::fromUtf8(language[lsDeleteFolder].c_str()) + "?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ delete folder;
+ }
+ break;
+ case NODE_FUNCTION:
+ {
+ FunctionBundle *func = reinterpret_cast<FunctionBundle *>(node->data());
+ if (MessageDialog::question(this, QString::fromUtf8(language[lsDeleteFunction].c_str()) + "?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ for (size_t i = func->count(); i > 0; i--) {
+ delete func->item(i - 1)->func();
+ }
+ }
+ }
+ break;
+#ifdef ULTIMATE
+ case NODE_LICENSE:
+ {
+ License *license = reinterpret_cast<License *>(node->data());
+ if (MessageDialog::question(this, QString::fromUtf8(language[lsDeleteLicense].c_str()) + "?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ delete license;
+ }
+ break;
+ case NODE_FILE_FOLDER:
+ {
+ FileFolder *folder = reinterpret_cast<FileFolder *>(node->data());
+ if (MessageDialog::question(this, QString::fromUtf8(language[lsDeleteFolder].c_str()) + "?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ delete folder;
+ }
+ break;
+ case NODE_FILE:
+ {
+ InternalFile *file = reinterpret_cast<InternalFile *>(node->data());
+ if (MessageDialog::question(this, QString::fromUtf8(language[lsDeleteFile].c_str()) + "?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ delete file;
+ }
+ break;
+#endif
+ default:
+ {
+ QWidget *widget = focusWidget();
+ if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget))
+ edit->del();
+ else if (QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(widget))
+ edit->textCursor().removeSelectedText();
+ else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget))
+ comboBox->lineEdit()->del();
+ }
+ }
+}
+
+bool MainWindow::internalCompile()
+{
+ bool res = false;
+ try {
+ res = core_->Compile();
+ if (res && QFileInfo(QString::fromUtf8(core_->input_file()->file_name().c_str())) == QFileInfo(QString::fromUtf8(core_->absolute_output_file_name().c_str())))
+ fileChanged_ = false;
+ } catch(canceled_error &error) {
+ core_->Notify(mtWarning, NULL, error.what());
+ } catch(std::runtime_error &error) {
+ core_->Notify(mtError, NULL, error.what());
+ }
+ return res;
+}
+
+void MainWindow::compile()
+{
+ log_model_->clear();
+
+ {
+ QFutureWatcher<bool> watcher;
+ ProgressDialog progress(this);
+ log_->reset();
+
+ connect(&watcher, SIGNAL(finished()), &progress, SLOT(reject()));
+ connect(&progress, SIGNAL(cancel()), log_, SLOT(cancel()));
+ connect(log_, SIGNAL(startProgress(const QString &, unsigned long long)), &progress, SLOT(startProgress(const QString &, unsigned long long)));
+ connect(log_, SIGNAL(stepProgress(unsigned long long)), &progress, SLOT(stepProgress(unsigned long long)));
+
+ disconnect(log_, SIGNAL(notify(MessageType, IObject *, const QString &)), this, SLOT(notify(MessageType, IObject *, const QString &)));
+ connect(log_, SIGNAL(notify(MessageType, IObject *, const QString &)), this, SLOT(notify(MessageType, IObject *, const QString &)), Qt::BlockingQueuedConnection);
+
+ watcher.setFuture(QtConcurrent::run(this, &MainWindow::internalCompile));
+ progress.exec();
+ watcher.waitForFinished();
+
+ disconnect(log_, SIGNAL(notify(MessageType, IObject *, const QString &)), this, SLOT(notify(MessageType, IObject *, const QString &)));
+ connect(log_, SIGNAL(notify(MessageType, IObject *, const QString &)), this, SLOT(notify(MessageType, IObject *, const QString &)));
+
+ if (!watcher.result())
+ return;
+ }
+
+ if (save_act_->isEnabled() && settings_file().auto_save_project())
+ save();
+
+ if (execute_act_->isEnabled()) {
+ execute_protected_act_->setFullText(QString::fromUtf8(core_->absolute_output_file_name().c_str()));
+ execute_protected_act_->setVisible(true);
+ execute_menu_->setDefaultAction(execute_protected_act_);
+
+ if (MessageDialog::question(this, QString("%1.\n%2 \"%3\"?").arg(QString::fromUtf8(language[lsCompiled].c_str())).arg(QString::fromUtf8(language[lsExecute].c_str())).arg(execute_protected_act_->getFullText()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ executeProtected();
+ } else {
+ MessageDialog::information(this, QString::fromUtf8(language[lsCompiled].c_str()), QMessageBox::Ok);
+ }
+}
+
+void MainWindow::execute()
+{
+ if (execute_protected_act_->isVisible())
+ executeProtected();
+ else
+ executeOriginal();
+}
+
+void MainWindow::executeOriginal()
+{
+ executeFile(execute_original_act_->getFullText());
+}
+
+void MainWindow::executeProtected()
+{
+ executeFile(execute_protected_act_->getFullText());
+}
+
+void MainWindow::executeFile(const QString &fileName)
+{
+ QString commandLine = parameters_edit_->text().trimmed();
+#ifdef VMP_GNU
+ QStringList arguments;
+ if (!commandLine.isEmpty())
+ arguments << commandLine;
+ QProcess::startDetached(fileName, arguments, QFileInfo(fileName).absolutePath());
+#else
+ QString execCommand;
+ if (core_->input_file())
+ execCommand = QString::fromUtf8(core_->input_file()->exec_command().c_str());
+ if (execCommand.isEmpty())
+ ShellExecuteW(0, L"open", (LPCWSTR)fileName.utf16(), (LPCWSTR)commandLine.utf16(), (LPCWSTR)QFileInfo(fileName).absolutePath().utf16(), SW_SHOWNORMAL);
+ else
+ ShellExecuteW(0, L"open", (LPCWSTR)execCommand.utf16(), (LPCWSTR)(fileName + " " + commandLine).utf16(), (LPCWSTR)QFileInfo(fileName).absolutePath().utf16(), SW_SHOWNORMAL);
+#endif
+}
+
+#ifndef LITE
+static int luaErrGetLineNumber(const QString &text)
+{
+ int line = -1;
+ bool afterFirstSemicolon = false;
+ for(int pos = 0; pos < text.length(); pos++)
+ {
+ QChar ch = text.at(pos);
+ if(afterFirstSemicolon)
+ {
+ if(ch.isDigit())
+ {
+ if(line < 0)
+ line = 0;
+ line = 10 * line + ch.digitValue();
+ } else
+ {
+ break;
+ }
+ } else if(ch.toLatin1() == ':')
+ {
+ afterFirstSemicolon = true;
+ }
+ }
+ return line;
+}
+#endif
+
+void MainWindow::logItemDoubleClicked(const QModelIndex &index)
+{
+ ProjectNode *current = static_cast<ProjectNode *>(index.internalPointer());
+ if (!current || !current->data())
+ return;
+
+ IObject *sender = static_cast<IObject *>(current->data());
+ if (sender == core_->script()) {
+ icon_project_->setChecked(true);
+#ifndef LITE
+ project_tree_->setCurrentIndex(project_model_->scriptIndex());
+ int line = luaErrGetLineNumber(current->text());
+ if(line >= 1)
+ script_editor_->send(SCI_GOTOLINE, line - 1);
+#endif
+ } else if (sender == core_->watermark_manager()) {
+ icon_project_->setChecked(true);
+ project_tree_->setCurrentIndex(project_model_->optionsIndex());
+#ifndef LITE
+ core_property_editor_->setFocus();
+ core_property_editor_->setCurrentIndex(core_property_manager_->watermarkNameIndex());
+#endif
+ } else if (dynamic_cast<IFunction *>(sender)) {
+ icon_project_->setChecked(true);
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(sender));
+ }
+#ifdef ULTIMATE
+ else if (sender == core_->licensing_manager()) {
+ icon_project_->setChecked(true);
+ project_tree_->setCurrentIndex(project_model_->licensesIndex());
+ } else if (dynamic_cast<InternalFile *>(sender)) {
+ icon_project_->setChecked(true);
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(sender));
+ internal_file_property_editor_->setCurrentIndex(internal_file_property_manager_->fileNameIndex());
+ }
+#endif
+ else
+ return;
+
+ auto cw = project_page_->currentWidget();
+ if (cw)
+ cw->setFocus();
+}
+
+void MainWindow::functionItemDoubleClicked(const QModelIndex &index)
+{
+ Property *prop = function_property_manager_->indexToProperty(index);
+ if (!prop)
+ return;
+
+ if (CommandProperty *commandProp = qobject_cast<CommandProperty *>(prop)) {
+ ICommand *command = commandProp->value();
+ if (qobject_cast<CommandProperty *>(commandProp->parent())) {
+ // link
+ function_property_editor_->setCurrentIndex(function_property_manager_->commandToIndex(command));
+ return;
+ }
+
+ uint64_t branchAddress = command->link() ? command->link()->to_address() : 0;
+ if (branchAddress) {
+ IArchitecture *file = command->owner()->owner()->owner();
+ if (core_->input_file()->IndexOf(file) != NOT_ID) {
+ command = command->owner()->GetCommandByAddress(branchAddress);
+ if (command) {
+ function_property_editor_->setCurrentIndex(function_property_manager_->commandToIndex(command));
+ return;
+ }
+ goToAddress(file, branchAddress);
+ }
+ }
+ }
+}
+
+void MainWindow::disasmItemDoubleClicked(const QModelIndex &index)
+{
+#ifndef LITE
+ ICommand *command = disasm_model_->indexToCommand(index);
+ if (!command)
+ return;
+
+ uint64_t branchAddress = command->link() ? command->link()->to_address() : 0;
+ if (branchAddress)
+ goToAddress(disasm_model_->file(), branchAddress);
+#endif
+}
+
+void MainWindow::goToDump(IArchitecture *file, uint64_t address, bool mode)
+{
+#ifndef LITE
+ info_tree_->setCurrentIndex(info_model_->dumpIndex(file));
+ if (mode) {
+ QModelIndex index = dump_model_->addressToIndex(address);
+ if (index.isValid())
+ dump_view_->setCurrentIndex(index);
+ } else {
+ QModelIndex index = disasm_model_->addressToIndex(address);
+ if (index.isValid()) {
+ disasm_view_->scrollTo(index, QAbstractItemView::PositionAtTop);
+ // sometimes PositionAtTop works like PositionAtCenter
+ disasm_view_->scrollTo(index, QAbstractItemView::PositionAtTop);
+ disasm_view_->setCurrentIndex(index);
+ }
+ }
+#endif
+}
+
+void MainWindow::goToAddress(IArchitecture *file, uint64_t address)
+{
+#ifdef LITE
+ MapFunctionBundle *mapFunction = file->owner()->map_function_list()->GetFunctionByAddress(file, address);
+ if (mapFunction) {
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(mapFunction));
+ if (function_property_manager_->value()) {
+ ICommand *command = function_property_manager_->value()->GetCommandByAddress(file, address);
+ if (command) {
+ function_property_editor_->setCurrentIndex(function_property_manager_->commandToIndex(command));
+ return;
+ }
+ }
+ }
+#else
+ if (icon_details_->isChecked()) {
+ goToDump(file, address, dump_view_->hasFocus());
+ return;
+ }
+
+ ICommand *command = file->function_list()->GetCommandByAddress(address, false);
+ IFunction *project_function = command ? command->owner() : NULL;
+ MapFunctionBundle *mapFunction = file->owner()->map_function_list()->GetFunctionByAddress(file, address);
+
+ if (project_function && (icon_project_->isChecked() || !mapFunction)) {
+ icon_project_->setChecked(true);
+ project_tree_->setCurrentIndex(project_model_->objectToIndex(project_function));
+ function_property_editor_->setCurrentIndex(function_property_manager_->commandToIndex(command));
+ return;
+ } else if (mapFunction) {
+ icon_functions_->setChecked(true);
+ functions_tree_->setCurrentIndex(functions_model_->objectToIndex(mapFunction));
+ if (function_property_manager_->value()) {
+ command = function_property_manager_->value()->GetCommandByAddress(file, address);
+ if (command) {
+ function_property_editor_->setFocus();
+ function_property_editor_->setCurrentIndex(function_property_manager_->commandToIndex(command));
+ return;
+ }
+ }
+ }
+
+ icon_details_->setChecked(true);
+ goToDump(file, address);
+#endif
+}
+
+void MainWindow::goTo()
+{
+#ifndef LITE
+ FunctionDialog dialog(core_->input_file(), disasm_model_->file(), smGotoAddress, this);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ QList<AddressInfo> addresses = dialog.addresses();
+ if (addresses.isEmpty())
+ return;
+
+ AddressInfo info = addresses[0];
+ goToAddress(info.arch, info.address);
+ }
+#endif
+}
+
+bool MainWindow::isContextSearchApplicable()
+{
+ return project_page_->currentWidget() == script_editor_ ||
+#ifndef LITE
+ project_page_->currentWidget() == dump_page_ ||
+#endif
+ dynamic_cast<QTreeView *>(project_page_->currentWidget());
+}
+
+void MainWindow::search()
+{
+ if (isContextSearchApplicable()) {
+ if (!context_find_->isVisible()) {
+ context_find_->showAndClear(project_filter_->text());
+ } else {
+ context_find_->show();
+ }
+ return;
+ }
+ project_filter_->selectAll();
+ project_filter_->setFocus();
+}
+
+void MainWindow::showProtected()
+{
+ showCurrentObject();
+}
+
+void MainWindow::contextFindNext()
+{
+ contextFind(context_find_->text(), true, false);
+}
+
+void MainWindow::contextFindPrevious()
+{
+ contextFind(context_find_->text(), false, false);
+}
+
+void MainWindow::contextFind(const QString &ttf, bool forward, bool incremental)
+{
+ bool found = true;
+ if(!ttf.isEmpty())
+ {
+ if (project_page_->currentWidget() == script_editor_)
+ {
+ found = findInScript(ttf, forward, incremental);
+ } else if (QAbstractItemView *tv =
+#ifndef LITE
+ (project_page_->currentWidget() == dump_page_) ? (disasm_view_->geometry().height() ? (QAbstractItemView *)disasm_view_ : (QAbstractItemView *)dump_view_) :
+#endif
+ dynamic_cast<QAbstractItemView *>(project_page_->currentWidget()))
+ {
+ found = findInView(tv, ttf, forward, incremental);
+ }
+ }
+ if (!context_find_->isVisible())
+ context_find_->show();
+ context_find_->setPalette(found);
+}
+
+bool MainWindow::findInScript(const QString &ttf, bool forward, bool incremental)
+{
+ bool found = false;
+
+ uptr_t pos = script_editor_->send(SCI_GETCURRENTPOS),
+ anc = script_editor_->send(SCI_GETANCHOR);
+ if(!incremental)
+ {
+ if (forward) // set caret to the end of selection
+ {
+ script_editor_->send(SCI_GOTOPOS, std::max(anc, pos));
+ } else // set caret to the beginning of selection
+ {
+ script_editor_->send(SCI_GOTOPOS, std::min(anc, pos));
+ }
+ }
+
+ unsigned int iMessage = SCI_SEARCHPREV;
+ if (forward)
+ iMessage = SCI_SEARCHNEXT;
+ uptr_t wParam = 0;
+ if (context_find_->caseSensitive())
+ wParam = SCFIND_MATCHCASE;
+
+ while(!found)
+ {
+ script_editor_->send(SCI_SEARCHANCHOR);
+ found = (script_editor_->send(iMessage, wParam, (sptr_t)ttf.toUtf8().data()) != -1);
+
+ if (found)
+ {
+ script_editor_->send(SCI_SCROLLCARET);
+ } else
+ {
+ if(incremental) // try from the beginning
+ {
+ script_editor_->send(SCI_GOTOPOS);
+ incremental = false;
+ } else
+ {
+ script_editor_->send(SCI_SETSEL, anc, pos);
+ break;
+ }
+ }
+ }
+ return found;
+}
+
+bool MainWindow::findInView(QAbstractItemView *tv, const QString &ttf, bool forward, bool incremental)
+{
+ WaitCursor wc;
+
+ QRegExp term(ttf, context_find_->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive);
+ ItemModelSearcher searcher(
+ tv->model(),
+ tv->currentIndex(),
+ &term,
+ forward,
+ incremental);
+
+ QModelIndex ci = searcher.result();
+ bool found = ci.isValid();
+ if(found && ci != tv->currentIndex()) {
+ tv->selectionModel()->setCurrentIndex(ci, QItemSelectionModel::ClearAndSelect);
+ }
+ return found;
+}
+
+void MainWindow::contextFindClosed()
+{
+ QWidget *page = project_page_->currentWidget();
+ if (page)
+ page->setFocus();
+}
+
+void MainWindow::updateTemplates()
+{
+ QList<QAction*> actions = templates_menu_->actions();
+ ProjectTemplateManager *template_manager = core_->template_manager();
+ int separator_pos = actions.size() - 3;
+ size_t c = 0;
+ for (int i = 0; i < separator_pos; i++) {
+ QAction *action = actions.at(i);
+ if (i < (int)template_manager->count()) {
+ ProjectTemplate *pt = template_manager->item(i);
+ action->setText(QString::fromUtf8(pt->display_name().c_str()));
+ c++;
+ } else {
+ templates_menu_->removeAction(action);
+ }
+ }
+ for (size_t i = c; i < template_manager->count(); i++) {
+ ProjectTemplate *pt = template_manager->item(i);
+ QAction *action = new QAction(QString::fromUtf8(pt->display_name().c_str()), this);
+ action->setCheckable(true);
+ connect(action, SIGNAL(triggered()), this, SLOT(templateSelect()));
+ templates_menu_->insertAction(actions.at(separator_pos), action);
+ }
+}
+
+void MainWindow::templatesShow()
+{
+ QList<QAction*> actions = templates_menu_->actions();
+ ProjectTemplate current(NULL, "");
+ ProjectTemplateManager *template_manager = core_->template_manager();
+ current.ReadFromCore(*core_);
+ bool isChecked = false;
+ for (int i = 0; i < (int)template_manager->count(); i++) {
+ ProjectTemplate *pt = template_manager->item(i);
+ if (!isChecked && *pt == current) {
+ isChecked = true;
+ actions.at(i)->setChecked(true);
+ } else {
+ actions.at(i)->setChecked(false);
+ }
+ }
+}
+
+void MainWindow::templatesSave()
+{
+ TemplateSaveDialog dialog(core_->template_manager(), this);
+ if (dialog.exec() == QDialog::Accepted)
+ core_->template_manager()->Add(dialog.name().toUtf8().constData(), *core_);
+}
+
+void MainWindow::templatesEdit()
+{
+ TemplatesWindow dialog(this);
+ dialog.exec();
+}
+
+void MainWindow::templateSelect()
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ if (action) {
+ core_property_editor_->closePersistentEditor(core_property_editor_->currentIndex());
+ core_->LoadFromTemplate(*core_->template_manager()->item(templates_menu_->actions().indexOf(action)));
+ }
+}
+
+void MainWindow::updateEditActions()
+{
+ if (project_model_->isEmpty())
+ return;
+
+ if (QApplication::activeWindow() != this)
+ return;
+
+ QWidget *widget = focusWidget();
+ bool canCopy = false;
+#ifdef ULTIMATE
+ if (widget == license_property_editor_ && license_property_manager_->indexToProperty(license_property_editor_->currentIndex()) == license_property_manager_->serialNumber())
+ canCopy = true;
+#endif
+ bool canCut = false;
+ bool canPaste = false;
+ bool canRedo = false;
+ bool canUndo = false;
+ ProjectNode *current = currentProjectNode();
+ assert(current);
+ if (!current)
+ return;
+#ifdef ULTIMATE
+ add_license_act2_->setVisible(current->type() == NODE_LICENSE || current->type() == NODE_LICENSES);
+ add_file_act2_->setVisible(current->type() == NODE_FILE || current->type() == NODE_FILE_FOLDER || current->type() == NODE_FILES || current->type() == NODE_ASSEMBLIES);
+ add_function_act2_->setVisible(!add_license_act2_->isEnabled() && !add_file_act2_->isEnabled());
+#endif
+#ifndef LITE
+ add_function_act2_->setVisible(current->type() == NODE_FUNCTIONS || current->type() == NODE_FOLDER || current->type() == NODE_FUNCTION);
+#endif
+
+ bool canDel = current->type() == NODE_SCRIPT || current->type() == NODE_SCRIPT_BOOKMARK || current->type() == NODE_FUNCTION || current->type() == NODE_FOLDER || current->type() == NODE_LICENSE || current->type() == NODE_FILE_FOLDER || current->type() == NODE_FILE;
+ if (widget == script_editor_) {
+ canUndo = script_editor_->canUndo();
+ canRedo = script_editor_->canRedo();
+ canCopy = script_editor_->hasSelection();
+ canCut = script_editor_->hasSelection();
+ canDel = script_editor_->hasSelection();
+ canPaste = script_editor_->canPaste();
+ } else if (QAbstractItemView *view = qobject_cast<QAbstractItemView *>(widget)) {
+ canCopy = view->selectionModel()->selectedIndexes().size() > 0;
+ canDel = canCopy && currentTreeView() == project_tree_;
+#ifdef ULTIMATE
+ } else if (widget == license_property_editor_ && license_property_manager_->indexToProperty(license_property_editor_->currentIndex()) == license_property_manager_->serialNumber()) {
+ canCopy = true;
+#endif
+ } else if (QLineEdit *edit = qobject_cast<QLineEdit *>(widget)) {
+ canCopy = edit->hasSelectedText();
+ if (!edit->isReadOnly()) {
+ canPaste = !QApplication::clipboard()->text().isEmpty();
+ canCut = edit->hasSelectedText();
+ canDel = edit->hasSelectedText();
+ canRedo = edit->isRedoAvailable();
+ canUndo = edit->isUndoAvailable();
+ }
+ } else if (QPlainTextEdit *pt_edit = qobject_cast<QPlainTextEdit *>(widget)) {
+ canCopy = pt_edit->textCursor().hasSelection();
+ if (!pt_edit->isReadOnly()) {
+ canPaste = !QApplication::clipboard()->text().isEmpty();
+ canCut = pt_edit->textCursor().hasSelection();
+ canDel = pt_edit->textCursor().hasSelection();
+ canRedo = pt_edit->document()->isRedoAvailable();
+ canUndo = pt_edit->document()->isUndoAvailable();
+ }
+ } else if (QComboBox *comboBox = qobject_cast<QComboBox *>(widget)) {
+ if (comboBox->isEditable()) {
+ QLineEdit *edit = comboBox->lineEdit();
+ canCopy = edit->hasSelectedText();
+ if (!edit->isReadOnly()) {
+ canPaste = !QApplication::clipboard()->text().isEmpty();
+ canCut = edit->hasSelectedText();
+ canDel = edit->hasSelectedText();
+ canRedo = edit->isRedoAvailable();
+ canUndo = edit->isUndoAvailable();
+ }
+ }
+ }
+ copy_act_->setEnabled(canCopy);
+ cut_act_->setEnabled(canCut);
+ paste_act_->setEnabled(canPaste);
+ redo_act_->setEnabled(canRedo);
+ undo_act_->setEnabled(canUndo);
+ delete_act_->setEnabled(canDel);
+
+ if (fileChanged_) {
+ fileChanged_ = false;
+ if (MessageDialog::question(this, QString::fromUtf8(string_format(language[lsWatchedFileChange].c_str(), core_->input_file()->file_name().c_str()).c_str()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ recent_file_ = 0;
+ openRecentFile();
+ }
+ }
+}
+
+void MainWindow::treeSectionClicked(int index)
+{
+ ProjectNode *current = currentProjectNode();
+ if (!current)
+ return;
+
+ project_model_->sortNode(current, index);
+ directory_model_->setDirectory(current);
+}
+
+void MainWindow::fileChanged(const QString & path)
+{
+ fileChanged_ = true;
+} \ No newline at end of file