Page MenuHomePhabricator

No OneTemporary

Size
82 KB
Referenced Files
None
Subscribers
None
diff --git a/trunk/dlgpreferences.cpp b/trunk/dlgpreferences.cpp
index c96f4eb..077e2ac 100644
--- a/trunk/dlgpreferences.cpp
+++ b/trunk/dlgpreferences.cpp
@@ -1,211 +1,215 @@
#include "dlgpreferences.h"
#include "ui_dlgpreferences.h"
#include <QString>
#include <QStringList>
#include <QListIterator>
#include <QModelIndexList>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
/*******************************************************************************
* Public
******************************************************************************/
DlgPreferences::DlgPreferences(Settings *p_sets, QWidget *p_parent) :
QDialog(p_parent), ui(new Ui::DlgPreferences)
{
ui->setupUi(this);
this->p_settings=p_sets;
// Load current values
this->LoadPreferences();
}
DlgPreferences::~DlgPreferences() {
delete ui;
}
/*******************************************************************************
* Private slots
******************************************************************************/
void DlgPreferences::on_BtnCancel_clicked() {
this->reject();
}
void DlgPreferences::on_ListReportLocations_clicked(const QModelIndex &index) {
if(!index.isValid()) {
// No valid row selected, disable some buttons
this->ui->BtnEditReportLoc->setEnabled(false);
this->ui->BtnRemoveReportLoc->setEnabled(false);
this->ui->BtnMoveReportLocUp->setEnabled(false);
this->ui->BtnMoveReportLocDown->setEnabled(false);
this->ui->BtnAddReportLoc->setFocus();
return;
}
if(this->ui->ListReportLocations->count()==1) {
// Only one item left, disable up/down buttons
this->ui->BtnEditReportLoc->setEnabled(true);
this->ui->BtnRemoveReportLoc->setEnabled(true);
this->ui->BtnMoveReportLocUp->setEnabled(false);
this->ui->BtnMoveReportLocDown->setEnabled(false);
return;
}
if(index.row()==0) {
// First row selected, disable up button
this->ui->BtnEditReportLoc->setEnabled(true);
this->ui->BtnRemoveReportLoc->setEnabled(true);
this->ui->BtnMoveReportLocUp->setEnabled(false);
this->ui->BtnMoveReportLocDown->setEnabled(true);
return;
}
if(index.row()==(this->ui->ListReportLocations->count()-1)) {
// Last row selected, disable down button
this->ui->BtnEditReportLoc->setEnabled(true);
this->ui->BtnRemoveReportLoc->setEnabled(true);
this->ui->BtnMoveReportLocUp->setEnabled(true);
this->ui->BtnMoveReportLocDown->setEnabled(false);
return;
}
// Any other valid row selected, enable up/down buttons
this->ui->BtnEditReportLoc->setEnabled(true);
this->ui->BtnRemoveReportLoc->setEnabled(true);
this->ui->BtnMoveReportLocUp->setEnabled(true);
this->ui->BtnMoveReportLocDown->setEnabled(true);
}
void DlgPreferences::on_BtnAddReportLoc_clicked() {
QString new_loc=QFileDialog::getExistingDirectory(this,
tr("Select new report "
"directory"));
if(!new_loc.isEmpty()) {
this->ui->ListReportLocations->addItem(new_loc);
}
}
void DlgPreferences::on_BtnEditReportLoc_clicked() {
QModelIndex cur_item=this->ui->ListReportLocations->currentIndex();
if(!cur_item.isValid()) return;
// Get selected item
QListWidgetItem *p_item=this->ui->ListReportLocations->item(cur_item.row());
// Let user select new directory
QString new_loc=QFileDialog::getExistingDirectory(this,
tr("Edit report directory"),
p_item->text());
if(!new_loc.isEmpty()) {
p_item->setText(new_loc);
}
}
void DlgPreferences::on_BtnRemoveReportLoc_clicked() {
QModelIndex cur_item=this->ui->ListReportLocations->currentIndex();
if(!cur_item.isValid()) return;
QListWidgetItem *p_item=
this->ui->ListReportLocations->takeItem(cur_item.row());
delete p_item;
// Update buttons
this->on_ListReportLocations_clicked(
this->ui->ListReportLocations->currentIndex());
}
void DlgPreferences::on_BtnMoveReportLocUp_clicked() {
QModelIndex cur_item=this->ui->ListReportLocations->currentIndex();
if(!cur_item.isValid() || cur_item.row()==0) return;
// Move selected item up
QListWidgetItem *p_item=
this->ui->ListReportLocations->takeItem(cur_item.row());
this->ui->ListReportLocations->insertItem(cur_item.row()-1,p_item);
// Reselect moved item and update buttons
this->ui->ListReportLocations->setCurrentItem(p_item);
this->on_ListReportLocations_clicked(
this->ui->ListReportLocations->currentIndex());
}
void DlgPreferences::on_BtnMoveReportLocDown_clicked() {
QModelIndex cur_item=this->ui->ListReportLocations->currentIndex();
if(!cur_item.isValid() ||
cur_item.row()==(this->ui->ListReportLocations->count()-1))
{
return;
}
// Move selected item up
QListWidgetItem *p_item=
this->ui->ListReportLocations->takeItem(cur_item.row());
this->ui->ListReportLocations->insertItem(cur_item.row()+1,p_item);
// Reselect moved item and update buttons
this->ui->ListReportLocations->setCurrentItem(p_item);
this->on_ListReportLocations_clicked(
this->ui->ListReportLocations->currentIndex());
}
void DlgPreferences::on_BtnReset_clicked() {
if(QMessageBox::warning(this,
tr("Reset default settings"),
tr("Are you sure to reset all settings to their defaults?"),
QMessageBox::No,
QMessageBox::Yes)==QMessageBox::Yes)
{
this->p_settings->Reset();
this->LoadPreferences();
}
}
void DlgPreferences::on_BtnOk_clicked() {
this->SavePreferences();
this->accept();
}
/*******************************************************************************
* Private
******************************************************************************/
void DlgPreferences::LoadPreferences() {
// Load general preferences
- this->ui->SpinBoxRecentFiles->
- setValue(this->p_settings->GetRecentFilesDepth());
- this->ui->ChkBoxSavePositions->
- setChecked(this->p_settings->GetWindowGeometryStatus());
+ this->ui->SpinBoxRecentFiles->setValue(
+ this->p_settings->GetRecentFilesDepth());
+ this->ui->ChkBoxSavePositions->setChecked(
+ this->p_settings->GetWindowGeometryStatus());
+ this->ui->ChkBoxOpenReadOnly->setChecked(
+ this->p_settings->GetOpenHivesReadOnly());
// Populate report location list
this->ui->ListReportLocations->clear();
QStringList report_dirs=this->p_settings->GetReportTemplateDirs();
QListIterator<QString> it_report_dirs(report_dirs);
if(!report_dirs.isEmpty()) {
while(it_report_dirs.hasNext()) {
this->ui->ListReportLocations->addItem(it_report_dirs.next());
}
this->ui->ListReportLocations->setCurrentRow(0);
this->ui->BtnEditReportLoc->setEnabled(true);
this->ui->BtnRemoveReportLoc->setEnabled(true);
this->ui->BtnMoveReportLocDown->setEnabled(true);
}
}
void DlgPreferences::SavePreferences() {
// Save general preferences
this->p_settings->SetRecentFilesDepth(this->ui->SpinBoxRecentFiles->value());
this->p_settings->SetWindowGeometryStatus(
this->ui->ChkBoxSavePositions->isChecked());
+ this->p_settings->SetOpenHivesReadOnly(
+ this->ui->ChkBoxOpenReadOnly->isChecked());
// Save report location list
QStringList report_dirs;
for(int i=0;i<this->ui->ListReportLocations->count();i++) {
report_dirs.append(this->ui->ListReportLocations->item(i)->text());
}
this->p_settings->SetReportTemplateDirs(report_dirs);
}
diff --git a/trunk/dlgpreferences.ui b/trunk/dlgpreferences.ui
index bf14b80..ab96fa5 100644
--- a/trunk/dlgpreferences.ui
+++ b/trunk/dlgpreferences.ui
@@ -1,233 +1,253 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgPreferences</class>
<widget class="QDialog" name="DlgPreferences">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>615</width>
<height>404</height>
</rect>
</property>
<property name="windowTitle">
<string>Preferences</string>
</property>
<property name="windowIcon">
<iconset resource="fred.qrc">
<normaloff>:/icons/resources/fred.png</normaloff>:/icons/resources/fred.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="TabGeneral">
<attribute name="title">
<string>General</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QSpinBox" name="SpinBoxRecentFiles"/>
</item>
- <item row="0" column="0">
- <widget class="QLabel" name="LblRecentFiles">
- <property name="text">
- <string>Number of recent files to remember:</string>
- </property>
- </widget>
- </item>
<item row="1" column="0">
<widget class="QLabel" name="LblSavePositions">
<property name="text">
<string>Save position and size of main window and dialogs:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="ChkBoxSavePositions">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="0" column="0">
+ <widget class="QLabel" name="LblRecentFiles">
+ <property name="text">
+ <string>Number of recent files to remember:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="LblOpenReadOnly">
+ <property name="text">
+ <string>Always open files read-only:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="ChkBoxOpenReadOnly">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="TabReports">
<attribute name="title">
<string>Reports</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Warning:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The following list gives you the possibility to add/remove report locations and to change their precedence. Reports are searched and added from top to bottom, thus reports found in later directories replace reports found earlier if they have same name, category and hive! In addition, you may also remove the two default system and user locations which might result in no reports being found at all if you don't have added your own locations.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QListWidget" name="ListReportLocations"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="BtnAddReportLoc">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="BtnEditReportLoc">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="BtnRemoveReportLoc">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="BtnMoveReportLocUp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Move up</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="BtnMoveReportLocDown">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Move down</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="BtnCancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="BtnReset">
<property name="text">
<string>Reset to defaults</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="BtnOk">
<property name="text">
<string>&amp;Ok</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>BtnOk</tabstop>
<tabstop>BtnCancel</tabstop>
<tabstop>BtnReset</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>SpinBoxRecentFiles</tabstop>
<tabstop>ChkBoxSavePositions</tabstop>
<tabstop>ListReportLocations</tabstop>
<tabstop>BtnAddReportLoc</tabstop>
<tabstop>BtnEditReportLoc</tabstop>
<tabstop>BtnRemoveReportLoc</tabstop>
<tabstop>BtnMoveReportLocUp</tabstop>
<tabstop>BtnMoveReportLocDown</tabstop>
</tabstops>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index 05a6bcf..c6ad39f 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,673 +1,708 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef FRED_REPORT_TEMPLATE_DIR
#ifndef __MINGW32__
#define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/"
#else
#define FRED_REPORT_TEMPLATE_DIR ".\\report_templates\\"
#endif
#endif
#include <QFileDialog>
#include <QMessageBox>
#include <QStringList>
#include <QDesktopWidget>
#include <QDir>
#include <QSplitter>
#include <QListIterator>
#include <QDebug>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
#include "dlgreportchooser.h"
#include "dlgreportviewer.h"
#include "dlgsearch.h"
#include "dlgpreferences.h"
#include "compileinfo.h"
/*******************************************************************************
* Public
******************************************************************************/
MainWindow::MainWindow(ArgParser *p_arg_parser) :
QMainWindow(0), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Initialize private vars
this->p_args=p_arg_parser;
this->p_hive=new RegistryHive(this);
this->is_hive_open=false;
this->p_reg_node_tree_model=NULL;
this->p_reg_node_tree_model_proxy=NULL;
this->p_reg_key_table_model=NULL;
this->p_search_thread=NULL;
this->search_result_widgets.clear();
- // Init settings
+ // Init and load settings
this->p_settings=new Settings(this);
+ this->is_hive_writable=!this->p_settings->GetOpenHivesReadOnly();
// Set main window size
QByteArray geometry=this->p_settings->GetWindowGeometry("MainWindow");
if(!geometry.isEmpty()) {
// Restore saved geometry
this->restoreGeometry(geometry);
} else {
// No saved geometry, calculate and set default
int cur_screen=QApplication::desktop()->screenNumber(this);
int window_width=
QApplication::desktop()->availableGeometry(cur_screen).width()*0.5;
int window_height=
QApplication::desktop()->availableGeometry(cur_screen).height()*0.5;
int window_x=
(QApplication::desktop()->availableGeometry(cur_screen).width()/2)-
(window_width/2);
int window_y=
(QApplication::desktop()->availableGeometry(cur_screen).height()/2)-
(window_height/2);
this->setGeometry(window_x,
window_y,
window_width,
window_height);
}
// Create widgets
this->p_horizontal_splitter=new QSplitter();
this->p_horizontal_splitter->setOrientation(Qt::Horizontal);
this->p_node_tree=new RegistryNodeTree(this->p_horizontal_splitter);
this->p_vertical_splitter=new QSplitter(this->p_horizontal_splitter);
this->p_vertical_splitter->setOrientation(Qt::Vertical);
this->p_key_table=new RegistryKeyTable(this->p_vertical_splitter);
this->p_tab_widget=new TabWidget(this->p_vertical_splitter);
this->p_hex_edit_widget=new HexEditWidget();
// Add hexedit page to tab_widget
this->p_tab_widget->addTab(this->p_hex_edit_widget,tr("Hex viewer"));
// Add widgets to their splitters
this->p_vertical_splitter->addWidget(this->p_key_table);
this->p_vertical_splitter->addWidget(this->p_tab_widget);
this->p_horizontal_splitter->addWidget(this->p_node_tree);
this->p_horizontal_splitter->addWidget(this->p_vertical_splitter);
// Set stretch factors
QSizePolicy node_tree_policy=this->p_node_tree->sizePolicy();
node_tree_policy.setHorizontalStretch(1);
node_tree_policy.setVerticalStretch(100);
this->p_node_tree->setSizePolicy(node_tree_policy);
QSizePolicy vertical_splitter_policy=this->p_vertical_splitter->sizePolicy();
vertical_splitter_policy.setHorizontalStretch(4);
vertical_splitter_policy.setVerticalStretch(100);
this->p_vertical_splitter->setSizePolicy(vertical_splitter_policy);
QSizePolicy key_table_policy=this->p_key_table->sizePolicy();
key_table_policy.setVerticalStretch(5);
key_table_policy.setHorizontalStretch(100);
this->p_key_table->setSizePolicy(key_table_policy);
QSizePolicy tab_widget_policy=this->p_tab_widget->sizePolicy();
tab_widget_policy.setVerticalStretch(2);
tab_widget_policy.setHorizontalStretch(200);
this->p_tab_widget->setSizePolicy(tab_widget_policy);
// Connect signals
this->connect(this->p_node_tree,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(activated(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(CurrentItemChanged(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotKeyTableDoubleClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(CurrentItemChanged(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_tab_widget,
SIGNAL(tabCloseRequested(int)),
this,
SLOT(SlotTabCloseButtonClicked(int)));
// Add central widget
this->setCentralWidget(this->p_horizontal_splitter);
this->centralWidget()->setContentsMargins(4,4,4,0);
// Set window title
this->UpdateWindowTitle();
// Create and update recently opened menu
this->p_recently_opened_menu=new QMenu(this);
this->ui->ActionRecentlyOpened->setMenu(this->p_recently_opened_menu);
this->UpdateRecentlyOpenedMenu();
+ // Update EnableWriteSupport menu according to defaults
+ this->UpdateEnableWriteSupportMenu();
+
// Load report templates
this->p_reports=new Reports(this->p_settings);
// Finally, react on some command line arguments
if(this->p_args->IsSet("maximized")) {
this->setWindowState(Qt::WindowMaximized);
}
if(this->p_args->IsSet("fullscreen")) {
this->setWindowState(Qt::WindowFullScreen);
}
if(this->p_args->IsSet("hive-file")) {
this->OpenHive(this->p_args->GetArgVal("hive-file"));
}
}
MainWindow::~MainWindow() {
if(this->is_hive_open) {
this->p_hive->Close();
}
// Delete created objects
delete this->p_reports;
this->ClearRecentlyOpenedMenu();
delete this->p_recently_opened_menu;
delete this->p_hex_edit_widget;
delete this->p_tab_widget;
delete this->p_key_table;
delete this->p_vertical_splitter;
delete this->p_node_tree;
delete this->p_horizontal_splitter;
delete this->p_settings;
delete this->p_hive;
delete ui;
}
/*******************************************************************************
* Protected
******************************************************************************/
void MainWindow::closeEvent(QCloseEvent *p_event) {
Q_UNUSED(p_event)
// Save window position and size on exit
this->p_settings->SetWindowGeometry("MainWindow",this->saveGeometry());
QMainWindow::closeEvent(p_event);
}
/*******************************************************************************
* Private slots
******************************************************************************/
-void MainWindow::on_action_Quit_triggered() {
- qApp->exit();
-}
-
void MainWindow::on_action_Open_hive_triggered() {
QString hive_file="";
hive_file=QFileDialog::getOpenFileName(this,
tr("Open registry hive"),
this->p_settings->GetLastOpenLocation(),
tr("All files (*)"));
if(hive_file=="") return;
this->OpenHive(hive_file);
}
void MainWindow::on_action_Close_hive_triggered() {
if(this->is_hive_open) {
// Remove search results
while(this->p_tab_widget->count()>1) {
this->p_tab_widget->removeTab(this->p_tab_widget->count()-1);
delete this->search_result_widgets.at(this->p_tab_widget->count()-1);
this->search_result_widgets.removeLast();
}
// Delete models
if(this->p_reg_node_tree_model!=NULL) {
this->p_node_tree->setModel(NULL);
delete this->p_reg_node_tree_model_proxy;
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model_proxy=NULL;
this->p_reg_node_tree_model=NULL;
}
if(this->p_reg_key_table_model!=NULL) {
this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_reg_key_table_model=NULL;
}
// Remove any data from hex edit and data interpreter
this->p_hex_edit_widget->SetData(QByteArray());
this->p_hex_edit_widget->setEnabled(false);
// Close hive
this->p_hive->Close();
this->is_hive_open=false;
- this->ui->action_Close_hive->setEnabled(false);
- this->ui->ActionSearch->setEnabled(false);
- this->ui->MenuReports->setEnabled(false);
+ this->is_hive_writable=!this->p_settings->GetOpenHivesReadOnly();
this->UpdateWindowTitle();
+ this->UpdateMenuStates();
+ this->UpdateEnableWriteSupportMenu();
}
}
-void MainWindow::on_actionAbout_Qt_triggered() {
- QMessageBox::aboutQt(this,tr("About Qt"));
-}
-
-void MainWindow::on_actionAbout_fred_triggered() {
- DlgAbout dlg_about(this);
- dlg_about.exec();
+void MainWindow::on_action_Quit_triggered() {
+ qApp->exit();
}
void MainWindow::on_ActionSearch_triggered() {
DlgSearch dlg_search(this);
if(dlg_search.exec()==QDialog::Accepted) {
// Create search thread and connect needed signals/slots
this->p_search_thread=new ThreadSearch(this);
// Add new search widget to tabwidget and to internal widget list
SearchResultWidget *p_search_widget=
new SearchResultWidget(this->p_tab_widget);
p_search_widget->setEnabled(false);
this->search_result_widgets.append(p_search_widget);
this->connect(p_search_widget,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotSearchResultWidgetDoubleClicked(QModelIndex)));
this->p_tab_widget->addTab(p_search_widget,tr("Search results"),true);
this->p_tab_widget->setCurrentIndex(this->p_tab_widget->count()-1);
// Connect search thread to result widget
this->connect(this->p_search_thread,
SIGNAL(SignalFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)),
p_search_widget,
SLOT(SlotFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)));
this->connect(this->p_search_thread,
SIGNAL(finished()),
this,
SLOT(SlotSearchFinished()));
this->connect(this->p_search_thread,
SIGNAL(finished()),
p_search_widget,
SLOT(SlotSearchFinished()));
// Start searching
this->ui->ActionSearch->setEnabled(false);
p_search_thread->Search(this->p_hive->Filename(),
dlg_search.Keywords(),
dlg_search.SearchNodeNames(),
dlg_search.SearchKeyNames(),
dlg_search.SearchKeyValues());
}
}
+void MainWindow::on_ActionEnableWriteSupport_triggered() {
+ this->is_hive_writable=!this->is_hive_writable;
+ this->UpdateEnableWriteSupportMenu();
+ this->p_node_tree->SetWritable(this->is_hive_writable);
+}
+
+void MainWindow::on_ActionPreferences_triggered() {
+ DlgPreferences dlg_preferences(this->p_settings,this);
+ dlg_preferences.exec();
+ // Update objects and GUI elements which might be affected by new settings
+ this->UpdateRecentlyOpenedMenu();
+ this->UpdateEnableWriteSupportMenu();
+ this->p_reports->LoadReportTemplates();
+}
+
void MainWindow::on_ActionGenerateReport_triggered() {
DlgReportChooser dlg_repchooser(this->p_reports,
this->p_hive->HiveTypeToString(
this->p_hive->HiveType()),
this->p_settings,
this);
if(dlg_repchooser.exec()==QDialog::Accepted) {
QList<ReportTemplate*> selected_reports;
// Get selected report
selected_reports=dlg_repchooser.GetSelectedReports();
if(selected_reports.isEmpty()) return;
// Generate report(s)
QString report_result="";
if(this->p_reports->GenerateReport(this->p_hive,
selected_reports,
report_result,
false))
{
// Report generation was successfull, show reports
DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_result,
this->p_settings,
this);
p_dlg_report_view->exec();
delete p_dlg_report_view;
} else {
// TODO: Inform user
qDebug()<<"ERROR: "<<report_result;
}
}
}
+void MainWindow::on_ActionReloadReportTemplates_triggered() {
+ this->p_reports->LoadReportTemplates();
+}
+
void MainWindow::SlotNodeTreeClicked(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
// Map proxy index to tree model index
index=this->p_reg_node_tree_model_proxy->mapToSource(index);
// Built node path
node_path=this->p_reg_node_tree_model->GetNodePath(index);
// Create table model and attach it to the table view
if(this->p_reg_key_table_model!=NULL) {
// If a previous model was set, delete it and clear hexedit etc...
this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_hex_edit_widget->SetData(QByteArray());
}
this->p_reg_key_table_model=new RegistryKeyTableModel(this->p_hive,node_path);
- this->p_key_table->setModel(this->p_reg_key_table_model);
+ this->p_key_table->setModel(this->p_reg_key_table_model,
+ this->is_hive_writable);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_node_tree->setFocus();
}
+void MainWindow::on_actionAbout_Qt_triggered() {
+ QMessageBox::aboutQt(this,tr("About Qt"));
+}
+
+void MainWindow::on_actionAbout_fred_triggered() {
+ DlgAbout dlg_about(this);
+ dlg_about.exec();
+}
+
void MainWindow::SlotKeyTableClicked(QModelIndex index) {
if(!index.isValid()) return;
this->selected_key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),2),
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
this->p_hex_edit_widget->SetData(this->selected_key_value);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_key_table->setFocus();
}
void MainWindow::SlotKeyTableDoubleClicked(QModelIndex index) {
Q_UNUSED(index);
/*
QModelIndex key_index;
QModelIndex node_index;
QStringList nodes;
QString key_name;
QString key_type;
QByteArray key_value;
if(!index.isValid()) return;
// Get key name, type and value
key_index=this->p_reg_key_table_model->index(index.row(),0);
key_name=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();
key_index=this->p_reg_key_table_model->index(index.row(),1);
key_type=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();ThreadSearch
key_index=this->p_reg_key_table_model->index(index.row(),2);
key_value=this->p_reg_key_table_model->data(key_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
// Get current node
node_index=this->p_node_tree->currentIndex();
//Built node path
nodes.clear();
nodes.append(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) {
// Prepend all parent nodes
node_index=this->p_reg_node_tree_model->parent(node_index);
nodes.prepend(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
}
DlgKeyDetails dlg_key_details(this);
dlg_key_details.SetValues(nodes,key_name,key_type,key_value);
dlg_key_details.exec();
*/
}
void MainWindow::SlotSearchFinished() {
delete this->p_search_thread;
this->p_search_thread=NULL;
this->ui->ActionSearch->setEnabled(true);
// Enable result widget
this->search_result_widgets.last()->setEnabled(true);
}
void MainWindow::SlotSearchResultWidgetDoubleClicked(QModelIndex index) {
SearchResultWidget *p_sender;
QString path;
QString match_type;
QString value;
QString key="";
int i;
if(!index.isValid()) return;
// Get pointer to sender
p_sender=(SearchResultWidget*)QObject::sender();
// Get path and matchtype
path=p_sender->item(index.row(),0)->text();
match_type=p_sender->item(index.row(),1)->text();
value=p_sender->item(index.row(),2)->text();
if(match_type==tr("Node name")) {
// Node name is not part of path. Add it
if(path=="\\") path.append(value);
else path.append("\\").append(value);
} else if(match_type==tr("Key name")) {
// Key name is stored in value
key=value;
} else if(match_type==tr("Key value")) {
// Key name is part of path. Save and remove it
QStringList nodes=path.split("\\",QString::SkipEmptyParts);
key=nodes.at(nodes.count()-1);
// Remove \<key name> from path
path.chop(key.length()+1);
}
// Expand treeview to correct node
QList<QModelIndex> indexes=
this->p_reg_node_tree_model->GetIndexListOf(path);
for(i=0;i<indexes.count();i++) {
indexes.replace(i,this->p_reg_node_tree_model_proxy->
mapFromSource(indexes.at(i)));
this->p_node_tree->expand(indexes.at(i));
}
if(indexes.count()>0) {
// Scroll to last expanded node, select it and update widgets
this->p_node_tree->scrollTo(indexes.at(indexes.count()-1),
QAbstractItemView::PositionAtCenter);
this->p_node_tree->selectionModel()->clear();
this->p_node_tree->selectionModel()->
select(indexes.at(indexes.count()-1),
QItemSelectionModel::Select);
// TODO: This does not work!!
this->SlotNodeTreeClicked(indexes.at(indexes.count()-1));
}
// Select correct key if search matched on keay name / value
if(key!="") {
int row=this->p_reg_key_table_model->GetKeyRow(key);
this->p_key_table->clearSelection();
this->p_key_table->scrollTo(this->p_reg_key_table_model->index(row,0),
QAbstractItemView::PositionAtCenter);
this->p_key_table->selectRow(row);
this->SlotKeyTableClicked(this->p_reg_key_table_model->index(row,0));
}
}
void MainWindow::SlotTabCloseButtonClicked(int index) {
// Delete tab widget and remove tab
this->p_tab_widget->removeTab(index);
delete this->search_result_widgets.at(index-1);
this->search_result_widgets.removeAt(index-1);
}
void MainWindow::SlotRecentlyOpenedFileClicked(bool checked) {
Q_UNUSED(checked)
QAction *p_sender=(QAction*)QObject::sender();
this->OpenHive(p_sender->text());
}
/*******************************************************************************
* Private
******************************************************************************/
-void MainWindow::CheckUserConfigDir() {
- QString user_config_dir=QDir::homePath()
- .append(QDir::separator())
- .append(".fred");
- if(!QDir(user_config_dir).exists()) {
- // User config dir does not exists, try to create it
- if(!QDir().mkpath(user_config_dir)) {
- // TODO: Maybe warn user
- return;
- }
- user_config_dir.append(QDir::separator()).append("report_templates");
- if(!QDir().mkpath(user_config_dir)) {
- // TODO: Maybe warn user
- return;
- }
- }
-}
-
-void MainWindow::UpdateWindowTitle(QString filename) {
- if(filename=="") {
- this->setWindowTitle(QString("%1 v%2").arg(APP_TITLE,APP_VERSION));
- } else {
- this->setWindowTitle(QString("%1 v%2 - %3").arg(APP_TITLE,
- APP_VERSION,
- filename.toLocal8Bit()
- .constData()));
- }
-}
-
void MainWindow::OpenHive(QString hive_file) {
// Update last open location
this->p_settings->SetLastOpenLocation(
hive_file.left(hive_file.lastIndexOf(QDir::separator())));
// If another hive is currently open, close it
if(this->is_hive_open) this->on_action_Close_hive_triggered();
// Try to open hive
- if(!this->p_hive->Open(hive_file)) {
+ if(!this->p_hive->Open(hive_file,this->is_hive_writable)) {
QMessageBox::critical(this,
tr("Error opening hive file"),
tr("Unable to open file '%1'").arg(hive_file));
return;
}
// Create tree model & proxy
this->p_reg_node_tree_model=new RegistryNodeTreeModel(this->p_hive);
this->p_reg_node_tree_model_proxy=new RegistryNodeTreeModelProxy(this);
//this->p_reg_node_tree_model_proxy->setDynamicSortFilter(true);
this->p_reg_node_tree_model_proxy->
setSourceModel(this->p_reg_node_tree_model);
- this->p_node_tree->setModel(this->p_reg_node_tree_model_proxy);
+ this->p_node_tree->setModel(this->p_reg_node_tree_model_proxy,
+ this->is_hive_writable);
this->is_hive_open=true;
- this->ui->action_Close_hive->setEnabled(true);
- this->ui->ActionSearch->setEnabled(true);
- this->ui->MenuReports->setEnabled(true);
// Enable data interpreter
this->p_hex_edit_widget->setEnabled(true);
// Update window title
this->UpdateWindowTitle(hive_file);
+ // Update menu states
+ this->UpdateMenuStates();
+
// Add file to recent list and update recently opened menu
this->p_settings->AddRecentFile(hive_file);
this->UpdateRecentlyOpenedMenu();
}
-void MainWindow::on_ActionReloadReportTemplates_triggered() {
- this->p_reports->LoadReportTemplates();
+void MainWindow::UpdateWindowTitle(QString filename) {
+ if(filename=="") {
+ this->setWindowTitle(QString("%1 v%2").arg(APP_TITLE,APP_VERSION));
+ } else {
+ this->setWindowTitle(QString("%1 v%2 - %3").arg(APP_TITLE,
+ APP_VERSION,
+ filename.toLocal8Bit()
+ .constData()));
+ if(!this->is_hive_writable) {
+ this->setWindowTitle(this->windowTitle().append(QString(" (%1)")
+ .arg(tr("read-only"))));
+ }
+ }
+}
+
+void MainWindow::UpdateMenuStates() {
+ if(this->is_hive_open) {
+ this->ui->action_Close_hive->setEnabled(true);
+ this->ui->ActionEnableWriteSupport->setEnabled(true);
+ this->ui->ActionSearch->setEnabled(true);
+ this->ui->ActionEnableWriteSupport->setEnabled(true);
+ this->ui->ActionGenerateReport->setEnabled(true);
+ this->ui->ActionReloadReportTemplates->setEnabled(true);
+ } else {
+ this->ui->action_Close_hive->setEnabled(false);
+ this->ui->ActionEnableWriteSupport->setEnabled(false);
+ this->ui->ActionSearch->setEnabled(false);
+ this->ui->ActionEnableWriteSupport->setEnabled(false);
+ this->ui->ActionGenerateReport->setEnabled(false);
+ this->ui->ActionReloadReportTemplates->setEnabled(false);
+ }
}
void MainWindow::ClearRecentlyOpenedMenu() {
QAction *p_action;
// Remove existing menu entries
QList<QAction*> menu_entries=this->p_recently_opened_menu->actions();
QListIterator<QAction*> it_me(menu_entries);
while(it_me.hasNext()) {
p_action=it_me.next();
this->p_recently_opened_menu->removeAction(p_action);
delete p_action;
}
}
void MainWindow::UpdateRecentlyOpenedMenu() {
QStringList recent_files=this->p_settings->GetRecentFiles();
QAction *p_action;
// Remove existing menu entries
this->ClearRecentlyOpenedMenu();
// If there are no recent files, disable submenu and return
if(recent_files.isEmpty()) {
this->ui->ActionRecentlyOpened->setEnabled(false);
return;
} else {
this->ui->ActionRecentlyOpened->setEnabled(true);
}
// Add recently opened files to menu
QListIterator<QString> it_rf(recent_files);
while(it_rf.hasNext()) {
// Create menu entry
p_action=new QAction(it_rf.next(),this->p_recently_opened_menu);
// Connect it to us
this->connect(p_action,
SIGNAL(triggered(bool)),
this,
SLOT(SlotRecentlyOpenedFileClicked(bool)));
// Add it to submenu
this->p_recently_opened_menu->addAction(p_action);
}
}
-void MainWindow::on_ActionPreferences_triggered() {
- DlgPreferences dlg_preferences(this->p_settings,this);
- dlg_preferences.exec();
- // Update objects and GUI elements which might be affected by new settings
- this->UpdateRecentlyOpenedMenu();
- this->p_reports->LoadReportTemplates();
+void MainWindow::UpdateEnableWriteSupportMenu() {
+ if(!this->is_hive_writable && this->p_settings->GetOpenHivesReadOnly()) {
+ this->ui->ActionEnableWriteSupport->setText(tr("Enable &write support"));
+ this->p_node_tree->SetWritable(false);
+ this->p_key_table->SetWritable(false);
+ } else {
+ this->ui->ActionEnableWriteSupport->setText(tr("Disable &write support"));
+ this->p_node_tree->SetWritable(true);
+ this->p_key_table->SetWritable(true);
+ }
+}
+
+/*
+void MainWindow::SetWriteSupport(bool enable) {
+
}
+*/
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index 7adfbf8..18845be 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,119 +1,121 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QLabel>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QSplitter>
#include <QString>
#include <QByteArray>
#include <hivex.h>
#include "argparser.h"
#include "registryhive.h"
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include "registrynodetreemodelproxy.h"
#include "registrykeytable.h"
#include "registrykeytablemodel.h"
#include "hexeditwidget.h"
#include "reports.h"
#include "threadsearch.h"
#include "searchresultwidget.h"
#include "tabwidget.h"
#include "settings.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(ArgParser *p_arg_parser);
~MainWindow();
protected:
void closeEvent(QCloseEvent *p_event);
private slots:
- void on_action_Quit_triggered();
void on_action_Open_hive_triggered();
void on_action_Close_hive_triggered();
- void on_actionAbout_Qt_triggered();
- void on_actionAbout_fred_triggered();
+ void on_action_Quit_triggered();
void on_ActionSearch_triggered();
+ void on_ActionEnableWriteSupport_triggered();
+ void on_ActionPreferences_triggered();
void on_ActionGenerateReport_triggered();
void on_ActionReloadReportTemplates_triggered();
+ void on_actionAbout_Qt_triggered();
+ void on_actionAbout_fred_triggered();
void SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
void SlotSearchFinished();
void SlotSearchResultWidgetDoubleClicked(QModelIndex index);
void SlotTabCloseButtonClicked(int index);
void SlotRecentlyOpenedFileClicked(bool checked);
- void on_ActionPreferences_triggered();
-
private:
Ui::MainWindow *ui;
ArgParser *p_args;
RegistryHive *p_hive;
bool is_hive_open;
+ bool is_hive_writable;
QByteArray selected_key_value;
QList<SearchResultWidget*> search_result_widgets;
Settings *p_settings;
// Models
RegistryNodeTreeModel *p_reg_node_tree_model;
RegistryNodeTreeModelProxy *p_reg_node_tree_model_proxy;
RegistryKeyTableModel *p_reg_key_table_model;
// Widgets etc...
RegistryNodeTree *p_node_tree;
RegistryKeyTable *p_key_table;
TabWidget *p_tab_widget;
HexEditWidget *p_hex_edit_widget;
QSplitter *p_horizontal_splitter;
QSplitter *p_vertical_splitter;
Reports *p_reports;
QMenu *p_recently_opened_menu;
// Threads
ThreadSearch *p_search_thread;
// Functions
- void CheckUserConfigDir();
- void UpdateWindowTitle(QString filename="");
void OpenHive(QString hive_file);
+ void UpdateWindowTitle(QString filename="");
+ void UpdateMenuStates();
void ClearRecentlyOpenedMenu();
void UpdateRecentlyOpenedMenu();
+ void UpdateEnableWriteSupportMenu();
};
#endif // MAINWINDOW_H
diff --git a/trunk/mainwindow.ui b/trunk/mainwindow.ui
index 6deca66..f71b0df 100644
--- a/trunk/mainwindow.ui
+++ b/trunk/mainwindow.ui
@@ -1,163 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>317</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="fred.qrc">
<normaloff>:/icons/resources/fred.png</normaloff>:/icons/resources/fred.png</iconset>
</property>
<widget class="QWidget" name="MainWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
- <height>29</height>
+ <height>27</height>
</rect>
</property>
<widget class="QMenu" name="MenuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="action_Open_hive"/>
<addaction name="ActionRecentlyOpened"/>
+ <addaction name="ActionSave"/>
<addaction name="action_Close_hive"/>
<addaction name="separator"/>
<addaction name="action_Quit"/>
</widget>
<widget class="QMenu" name="MenuHelp">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actionAbout_Qt"/>
<addaction name="actionAbout_fred"/>
</widget>
<widget class="QMenu" name="MenuReports">
<property name="enabled">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="title">
<string>&amp;Reports</string>
</property>
<addaction name="ActionGenerateReport"/>
<addaction name="ActionReloadReportTemplates"/>
</widget>
<widget class="QMenu" name="MenuEdit">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="ActionSearch"/>
<addaction name="separator"/>
+ <addaction name="ActionEnableWriteSupport"/>
<addaction name="ActionPreferences"/>
</widget>
<addaction name="MenuFile"/>
<addaction name="MenuEdit"/>
<addaction name="MenuReports"/>
<addaction name="MenuHelp"/>
</widget>
<widget class="QStatusBar" name="StatusBar"/>
<action name="action_Open_hive">
<property name="text">
<string>&amp;Open hive</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="action_Close_hive">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Close hive</string>
</property>
</action>
<action name="action_Quit">
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionAbout_Qt">
<property name="text">
<string>About Qt</string>
</property>
</action>
<action name="actionAbout_fred">
<property name="text">
<string>About fred</string>
</property>
</action>
<action name="ActionSearch">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Search</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="ActionPreferences">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preferences</string>
</property>
</action>
<action name="ActionGenerateReport">
<property name="enabled">
- <bool>true</bool>
+ <bool>false</bool>
</property>
<property name="text">
<string>Generate report</string>
</property>
</action>
<action name="ActionReloadReportTemplates">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
<property name="text">
<string>Reload report templates</string>
</property>
</action>
<action name="ActionRecentlyOpened">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Recently opened</string>
</property>
</action>
+ <action name="ActionEnableWriteSupport">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Enable &amp;write support</string>
+ </property>
+ </action>
+ <action name="ActionSave">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/registrykeytable.cpp b/trunk/registrykeytable.cpp
index ae4acc2..6583f68 100644
--- a/trunk/registrykeytable.cpp
+++ b/trunk/registrykeytable.cpp
@@ -1,145 +1,167 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrykeytable.h"
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
RegistryKeyTable::RegistryKeyTable(QWidget *p_parent) : QTableView(p_parent) {
+ this->is_writable=false;
+
// Configure widget
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->setAutoScroll(false);
this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
this->verticalHeader()->setHidden(true);
this->setTextElideMode(Qt::ElideNone);
// Create context menu
+ this->p_action_add_key=new QAction(tr("Add key"),this);
+ this->p_action_edit_key=new QAction(tr("Edit key"),this);
+ this->p_action_delete_key=new QAction(tr("Delete key"),this);
this->p_menu_copy=new QMenu(tr("Copy"),this);
this->p_action_copy_key_name=new QAction(tr("Key name"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_key_name);
this->connect(this->p_action_copy_key_name,
SIGNAL(triggered()),
this,
SLOT(SlotCopyKeyName()));
this->p_action_copy_key_value=new QAction(tr("Key value"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_key_value);
this->connect(this->p_action_copy_key_value,
SIGNAL(triggered()),
this,
SLOT(SlotCopyKeyValue()));
}
RegistryKeyTable::~RegistryKeyTable() {
// Delete context menu
delete this->p_action_copy_key_name;
delete this->p_action_copy_key_value;
delete this->p_menu_copy;
+ delete this->p_action_delete_key;
+ delete this->p_action_edit_key;
+ delete this->p_action_add_key;
}
-void RegistryKeyTable::setModel(QAbstractItemModel *p_model) {
+void RegistryKeyTable::setModel(QAbstractItemModel *p_model, bool writable) {
QTableView::setModel(p_model);
// Resize table rows / columns to fit data
this->resizeColumnsToContents();
this->resizeRowsToContents();
this->horizontalHeader()->stretchLastSection();
if(p_model!=NULL && p_model->rowCount()>0) {
// Select first table item
this->selectRow(0);
}
+
+ // Set writable status
+ this->SetWritable(writable);
+}
+
+void RegistryKeyTable::SetWritable(bool writable) {
+ this->is_writable=writable;
+ this->p_action_add_key->setEnabled(this->is_writable);
+ this->p_action_edit_key->setEnabled(this->is_writable);
+ this->p_action_delete_key->setEnabled(this->is_writable);
}
/*
void RegistryKeyTable::selectRow(QString key_name) {
int i;
this->clearSelection();
for(i=0;i<this->model()->rowCount();i++) {
if(this->model())
}
}
*/
int RegistryKeyTable::sizeHintForColumn(int column) const {
int size_hint=-1;
int i=0;
int item_width=0;
QFontMetrics fm(this->fontMetrics());
QModelIndex idx;
if(this->model()==NULL) return -1;
// Find string that needs the most amount of space
idx=this->model()->index(i,column);
while(idx.isValid()) {
item_width=fm.width(this->model()->data(idx).toString())+10;
if(item_width>size_hint) size_hint=item_width;
idx=this->model()->index(++i,column);
}
return size_hint;
}
void RegistryKeyTable::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a row is selected
if(this->selectedIndexes().count()!=3) return;
// Only show context menu when user clicked on selected row
if(!(this->indexAt(p_event->pos())==this->selectedIndexes().at(0) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(1) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(2)))
{
return;
}
// Emit a click signal
emit(this->clicked(this->indexAt(p_event->pos())));
// Create context menu and add actions
QMenu context_menu(this);
+ context_menu.addAction(this->p_action_add_key);
+ context_menu.addAction(this->p_action_edit_key);
+ context_menu.addAction(this->p_action_delete_key);
+ context_menu.addSeparator();
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
void RegistryKeyTable::currentChanged(const QModelIndex &current,
const QModelIndex &previous)
{
// Call parent class's currentChanged first
QTableView::currentChanged(current,previous);
// Now emit our signal
QModelIndex current_item=QModelIndex(current);
emit(RegistryKeyTable::CurrentItemChanged(current_item));
}
void RegistryKeyTable::SlotCopyKeyName() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(0).data().toString(),
QClipboard::Clipboard);
}
void RegistryKeyTable::SlotCopyKeyValue() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(2).data().toString(),
QClipboard::Clipboard);
}
diff --git a/trunk/registrykeytable.h b/trunk/registrykeytable.h
index 52f983a..f2833b7 100644
--- a/trunk/registrykeytable.h
+++ b/trunk/registrykeytable.h
@@ -1,58 +1,63 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYKEYTABLE_H
#define REGISTRYKEYTABLE_H
#include <QTableView>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
class RegistryKeyTable : public QTableView {
Q_OBJECT
public:
RegistryKeyTable(QWidget *p_parent=0);
~RegistryKeyTable();
- void setModel(QAbstractItemModel *p_model);
+ void setModel(QAbstractItemModel *p_model, bool writable=false);
+ void SetWritable(bool writable);
//void selectRow(QString key_name);
Q_SIGNALS:
void CurrentItemChanged(QModelIndex current);
protected:
int sizeHintForColumn(int column) const;
void contextMenuEvent(QContextMenuEvent *p_event);
private:
+ bool is_writable;
+ QAction *p_action_add_key;
+ QAction *p_action_edit_key;
+ QAction *p_action_delete_key;
QMenu *p_menu_copy;
QAction *p_action_copy_key_name;
QAction *p_action_copy_key_value;
void currentChanged(const QModelIndex &current,
const QModelIndex &previous);
private slots:
void SlotCopyKeyName();
void SlotCopyKeyValue();
};
#endif // REGISTRYKEYTABLE_H
diff --git a/trunk/registrynodetree.cpp b/trunk/registrynodetree.cpp
index 64cbd20..afe81a8 100644
--- a/trunk/registrynodetree.cpp
+++ b/trunk/registrynodetree.cpp
@@ -1,135 +1,157 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
RegistryNodeTree::RegistryNodeTree(QWidget *p_parent) : QTreeView(p_parent) {
+ this->is_writable=false;
+
// Configure widget
this->setTextElideMode(Qt::ElideNone);
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->sortByColumn(0,Qt::AscendingOrder);
this->setSortingEnabled(true);
// Create context menu
+ this->p_action_add_node=new QAction(tr("Add node"),this);
+ this->p_action_rename_node=new QAction(tr("Rename node"),this);
+ this->p_action_delete_node=new QAction(tr("Delete node"),this);
this->p_menu_copy=new QMenu(tr("Copy"),this);
this->p_action_copy_node_name=new QAction(tr("Node name"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_node_name);
this->connect(this->p_action_copy_node_name,
SIGNAL(triggered()),
this,
SLOT(SlotCopyNodeName()));
this->p_action_copy_node_path=new QAction(tr("Node path"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_node_path);
this->connect(this->p_action_copy_node_path,
SIGNAL(triggered()),
this,
SLOT(SlotCopyNodePath()));
}
RegistryNodeTree::~RegistryNodeTree() {
// Delete context menu
delete this->p_action_copy_node_name;
delete this->p_action_copy_node_path;
delete this->p_menu_copy;
+ delete this->p_action_delete_node;
+ delete this->p_action_rename_node;
+ delete this->p_action_add_node;
}
-void RegistryNodeTree::setModel(QAbstractItemModel *p_model) {
+void RegistryNodeTree::setModel(QAbstractItemModel *p_model, bool writable) {
// Assign model to view
QTreeView::setModel(p_model);
this->header()->setResizeMode(0,QHeaderView::ResizeToContents);
this->header()->setStretchLastSection(true);
if(p_model!=NULL && p_model->index(0,0).isValid()) {
// Select first tree item
this->setCurrentIndex(p_model->index(0,0));
}
+
+ // Set writable status
+ this->SetWritable(writable);
+}
+
+void RegistryNodeTree::SetWritable(bool writable) {
+ this->is_writable=writable;
+ this->p_action_add_node->setEnabled(this->is_writable);
+ this->p_action_rename_node->setEnabled(this->is_writable);
+ this->p_action_delete_node->setEnabled(this->is_writable);
}
void RegistryNodeTree::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a node is selected
if(this->selectedIndexes().count()!=2) return;
// Only show context menu when user clicked on selected row
// TODO: Does not work when clicking on column 2
if(this->indexAt(p_event->pos())!=this->selectedIndexes().at(0)) return;
// Emit a click signal
emit(this->clicked(this->indexAt(p_event->pos())));
// Create context menu and add actions
QMenu context_menu(this);
+ context_menu.addAction(this->p_action_add_node);
+ context_menu.addAction(this->p_action_rename_node);
+ context_menu.addAction(this->p_action_delete_node);
+ context_menu.addSeparator();
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
void RegistryNodeTree::keyPressEvent(QKeyEvent *p_event) {
// Only react if a node is selected and user pressed Key_Left
if(this->selectedIndexes().count()==2 &&
p_event->key()==Qt::Key_Left)
{
QModelIndex cur_index=this->selectedIndexes().at(0);
if(this->model()->hasChildren(cur_index) && this->isExpanded(cur_index)) {
// Current node is expanded. Only collapse this one
this->collapse(cur_index);
return;
}
if(!cur_index.parent().isValid()) {
// Do no try to collapse anything above root node
return;
}
this->collapse(cur_index.parent());
this->setCurrentIndex(cur_index.parent());
return;
}
// If we didn't handle the key event, let our parent handle it
QTreeView::keyPressEvent(p_event);
}
void RegistryNodeTree::currentChanged(const QModelIndex &current,
const QModelIndex &previous)
{
// Call parent class's currentChanged first
QTreeView::currentChanged(current,previous);
// Now emit our signal
QModelIndex current_item=QModelIndex(current);
emit(RegistryNodeTree::CurrentItemChanged(current_item));
}
void RegistryNodeTree::SlotCopyNodeName() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(0).data().toString(),
QClipboard::Clipboard);
}
void RegistryNodeTree::SlotCopyNodePath() {
QString path=((RegistryNodeTreeModel*)(this->model()))->
GetNodePath(this->selectedIndexes().at(0));
QApplication::clipboard()->setText(path,QClipboard::Clipboard);
}
diff --git a/trunk/registrynodetree.h b/trunk/registrynodetree.h
index 216f016..edf26e1 100644
--- a/trunk/registrynodetree.h
+++ b/trunk/registrynodetree.h
@@ -1,59 +1,64 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYNODETREE_H
#define REGISTRYNODETREE_H
#include <QTreeView>
#include <QAbstractItemModel>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
class RegistryNodeTree : public QTreeView {
Q_OBJECT
public:
RegistryNodeTree(QWidget *p_parent=0);
~RegistryNodeTree();
- void setModel(QAbstractItemModel *p_model);
+ void setModel(QAbstractItemModel *p_model, bool writable=false);
+ void SetWritable(bool writable);
Q_SIGNALS:
void CurrentItemChanged(QModelIndex current);
protected:
// int sizeHintForColumn(int column) const;
void contextMenuEvent(QContextMenuEvent *p_event);
void keyPressEvent(QKeyEvent *p_event);
private:
+ bool is_writable;
+ QAction *p_action_add_node;
+ QAction *p_action_rename_node;
+ QAction *p_action_delete_node;
QMenu *p_menu_copy;
QAction *p_action_copy_node_name;
QAction *p_action_copy_node_path;
void currentChanged(const QModelIndex &current,
const QModelIndex &previous);
private slots:
void SlotCopyNodeName();
void SlotCopyNodePath();
};
#endif // REGISTRYNODETREE_H
diff --git a/trunk/settings.cpp b/trunk/settings.cpp
index 2e2f3ac..e45a7dc 100644
--- a/trunk/settings.cpp
+++ b/trunk/settings.cpp
@@ -1,194 +1,206 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "settings.h"
#include <QDir>
#ifndef FRED_REPORT_TEMPLATE_DIR
#ifndef __MINGW32__
#define SYSTEM_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates"
#else
#define SYSTEM_REPORT_TEMPLATE_DIR ".\\report_templates\\"
#endif
#endif
#define APP_ORGANIZATION "pinguin.lu"
#define APP_NAME "fred"
// Default settings
#define DEFAULT_REPORT_TEMPLATE_DIRS QStringList()<<SYSTEM_REPORT_TEMPLATE_DIR \
<<this->user_report_template_dir
#define DEFAULT_WINDOW_GEOMETRY_STATUS true
#define DEFAULT_RECENT_FILES_DEPTH 5
#define DEFAULT_LAST_OPEN_LOCATION QDir::homePath()
+#define DEFAULT_OPEN_HIVES_READ_ONLY true
/*******************************************************************************
* Public
******************************************************************************/
Settings::Settings(QObject *p_parent) : QObject(p_parent) {
// Init vars
this->p_settings=NULL;
this->initialized=false;
this->user_settings_dir=QDir::homePath()
.append(QDir::separator()).append(".fred");
this->user_report_template_dir=QString(this->user_settings_dir)
.append(QDir::separator())
.append("report_templates");
// Make sure config dirs exist
if(!QDir(this->user_settings_dir).exists()) {
// User config dir does not exists, try to create it
if(!QDir().mkpath(this->user_settings_dir)) {
// TODO: Maybe warn user
return;
}
}
if(!QDir(this->user_report_template_dir).exists()) {
// Create config dir sub folder for report templates
if(!QDir().mkpath(this->user_report_template_dir)) {
// TODO: Maybe warn user
return;
}
}
// Create / open settings
#ifndef __MINGW32__
// On any Unix-like OS, settings should be saved in the .fred folder
this->p_settings=new QSettings(QString(this->user_settings_dir)
.append(QDir::separator())
.append("fred.conf"),
QSettings::NativeFormat,
this);
#else
// On Windows, it can be stored inside registry
this->p_settings=new QSettings(QSettings::NativeFormat,
QSettings::UserScope,
APP_ORGANIZATION,
APP_NAME,
this);
#endif
if(this->p_settings->status()!=QSettings::NoError ||
!this->p_settings->isWritable())
{
return;
}
this->initialized=true;
}
void Settings::Reset() {
if(!this->initialized) return;
// Clear all current settings
this->p_settings->clear();
}
void Settings::SetReportTemplateDirs(QStringList &dirs) {
if(!this->initialized) return;
this->p_settings->setValue("ReportTemplateDirs",dirs);
}
QStringList Settings::GetReportTemplateDirs() {
if(!this->initialized) return DEFAULT_REPORT_TEMPLATE_DIRS;
return this->p_settings->value("ReportTemplateDirs",
DEFAULT_REPORT_TEMPLATE_DIRS).toStringList();
}
void Settings::SetWindowGeometryStatus(bool save) {
if(!this->initialized) return;
this->p_settings->setValue("WindowGeometries/EnableSaving",save);
}
bool Settings::GetWindowGeometryStatus() {
if(!this->initialized) return DEFAULT_WINDOW_GEOMETRY_STATUS;
return this->p_settings->value("WindowGeometries/EnableSaving",
DEFAULT_WINDOW_GEOMETRY_STATUS).toBool();
}
void Settings::SetWindowGeometry(QString window_name, QByteArray geometry) {
if(!this->initialized || !this->GetWindowGeometryStatus()) return;
this->p_settings->setValue(QString("WindowGeometries/%1").arg(window_name),
geometry);
}
QByteArray Settings::GetWindowGeometry(QString window_name) {
if(!this->initialized || !this->GetWindowGeometryStatus()) {
return QByteArray();
}
return this->p_settings->value(QString("WindowGeometries/%1")
.arg(window_name)).toByteArray();
}
void Settings::SetRecentFilesDepth(int depth) {
if(!this->initialized) return;
this->p_settings->setValue("RecentFilesDepth",depth);
// Make sure there are currently not more recent files as allowed
QStringList recent_files=this->GetRecentFiles();
while(recent_files.count()>depth) recent_files.removeLast();
this->SetRecentFiles(recent_files);
}
int Settings::GetRecentFilesDepth() {
if(!this->initialized) return DEFAULT_RECENT_FILES_DEPTH;
return this->p_settings->value("RecentFilesDepth",
DEFAULT_RECENT_FILES_DEPTH).toInt();
}
void Settings::SetRecentFiles(QStringList &recent_files) {
if(!this->initialized) return;
this->p_settings->setValue("RecentFiles",recent_files);
}
void Settings::AddRecentFile(QString file) {
// Get recent files
QStringList recent_files=this->GetRecentFiles();
if(recent_files.contains(file)) {
// File already exists in recent list. Simply move it to top
recent_files.move(recent_files.indexOf(file),0);
} else {
// We only save RecentFilesDepth() files at max
while(recent_files.count()>=this->GetRecentFilesDepth())
recent_files.removeLast();
recent_files.prepend(file);
}
this->SetRecentFiles(recent_files);
}
QStringList Settings::GetRecentFiles() {
if(!this->initialized) return QStringList();
return this->p_settings->value("RecentFiles",QStringList()).toStringList();
}
void Settings::SetLastOpenLocation(QString dir) {
if(!this->initialized) return;
this->p_settings->setValue("LastOpenLocation",dir);
}
QString Settings::GetLastOpenLocation() {
if(!this->initialized) return DEFAULT_LAST_OPEN_LOCATION;
QString last_loc;
last_loc=this->p_settings->value("RecentFiles",
DEFAULT_LAST_OPEN_LOCATION).toString();
if(QDir(last_loc).exists()) return last_loc;
else return DEFAULT_LAST_OPEN_LOCATION;
}
+
+void Settings::SetOpenHivesReadOnly(bool read_only) {
+ if(!this->initialized) return;
+ this->p_settings->setValue("OpenFilesReadOnly",read_only);
+}
+
+bool Settings::GetOpenHivesReadOnly() {
+ if(!this->initialized) return DEFAULT_OPEN_HIVES_READ_ONLY;
+ return this->p_settings->value("OpenFilesReadOnly",
+ DEFAULT_OPEN_HIVES_READ_ONLY).toBool();
+}
diff --git a/trunk/settings.h b/trunk/settings.h
index 936d70f..57f92c5 100644
--- a/trunk/settings.h
+++ b/trunk/settings.h
@@ -1,62 +1,65 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QObject>
#include <QSettings>
#include <QString>
#include <QStringList>
#include <QByteArray>
class Settings : public QObject {
Q_OBJECT
public:
explicit Settings(QObject *p_parent=0);
void Reset();
void SetReportTemplateDirs(QStringList &dirs);
QStringList GetReportTemplateDirs();
void SetWindowGeometryStatus(bool save);
bool GetWindowGeometryStatus();
void SetWindowGeometry(QString window_name, QByteArray geometry);
QByteArray GetWindowGeometry(QString window_name);
void SetRecentFilesDepth(int depth);
int GetRecentFilesDepth();
void SetRecentFiles(QStringList &recent_files);
void AddRecentFile(QString file);
QStringList GetRecentFiles();
void SetLastOpenLocation(QString dir);
QString GetLastOpenLocation();
+ void SetOpenHivesReadOnly(bool read_only);
+ bool GetOpenHivesReadOnly();
+
private:
QSettings *p_settings;
bool initialized;
QString user_settings_dir;
QString user_report_template_dir;
};
#endif // SETTINGS_H

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 24, 3:10 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176987
Default Alt Text
(82 KB)

Event Timeline