Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUI: initial log viewer #9145

Merged
merged 1 commit into from Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions rpcs3/rpcs3.vcxproj
Expand Up @@ -472,6 +472,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_log_viewer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_main_window.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
Expand Down Expand Up @@ -762,6 +767,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_log_viewer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_main_window.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
Expand Down Expand Up @@ -1072,6 +1082,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_log_viewer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_main_window.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
Expand Down Expand Up @@ -1362,6 +1377,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_log_viewer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_main_window.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
Expand Down Expand Up @@ -1537,6 +1557,7 @@
<ClCompile Include="rpcs3qt\gui_application.cpp" />
<ClCompile Include="rpcs3qt\input_dialog.cpp" />
<ClCompile Include="rpcs3qt\localized.cpp" />
<ClCompile Include="rpcs3qt\log_viewer.cpp" />
<ClCompile Include="rpcs3qt\microphone_creator.cpp" />
<ClCompile Include="rpcs3qt\osk_dialog_frame.cpp" />
<ClCompile Include="rpcs3qt\pad_led_settings_dialog.cpp" />
Expand Down Expand Up @@ -2305,6 +2326,24 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
</CustomBuild>
<CustomBuild Include="rpcs3qt\log_viewer.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
</CustomBuild>
<ClInclude Include="rpcs3qt\numbered_widget_item.h" />
<ClInclude Include="rpcs3qt\richtext_item_delegate.h" />
<ClInclude Include="rpcs3qt\stylesheets.h" />
Expand Down
18 changes: 18 additions & 0 deletions rpcs3/rpcs3.vcxproj.filters
Expand Up @@ -1090,6 +1090,21 @@
<ClCompile Include="rpcs3qt\custom_table_widget_item.cpp">
<Filter>Gui\custom items</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\log_viewer.cpp">
<Filter>Gui\log</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_log_viewer.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_log_viewer.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_log_viewer.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_log_viewer.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Input\ds4_pad_handler.h">
Expand Down Expand Up @@ -1427,6 +1442,9 @@
<CustomBuild Include="rpcs3qt\localized_emu.h">
<Filter>Gui\settings</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\log_viewer.h">
<Filter>Gui\log</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<Image Include="rpcs3.ico" />
Expand Down
1 change: 1 addition & 0 deletions rpcs3/rpcs3qt/CMakeLists.txt
Expand Up @@ -34,6 +34,7 @@ set(SRC_FILES
localized.cpp
localized_emu.h
log_frame.cpp
log_viewer.cpp
main_window.cpp
memory_string_searcher.cpp
memory_viewer_panel.cpp
Expand Down
17 changes: 9 additions & 8 deletions rpcs3/rpcs3qt/cg_disasm_window.cpp
Expand Up @@ -63,13 +63,13 @@ cg_disasm_window::cg_disasm_window(std::shared_ptr<gui_settings> xSettings): xgu

void cg_disasm_window::ShowContextMenu(const QPoint &pos)
{
QMenu myMenu;
QMenu menu;
QAction* clear = new QAction(tr("&Clear"));
QAction* open = new QAction(tr("Open &Cg binary program"));

myMenu.addAction(open);
myMenu.addSeparator();
myMenu.addAction(clear);
menu.addAction(open);
menu.addSeparator();
menu.addAction(clear);

connect(clear, &QAction::triggered, [this]()
{
Expand All @@ -79,9 +79,10 @@ void cg_disasm_window::ShowContextMenu(const QPoint &pos)

connect(open, &QAction::triggered, [this]()
{
QString filePath = QFileDialog::getOpenFileName(this, tr("Select Cg program object"), m_path_last, tr("Cg program objects (*.fpo;*.vpo);;"));
if (filePath == NULL) return;
m_path_last = filePath;
const QString file_path = QFileDialog::getOpenFileName(this, tr("Select Cg program object"), m_path_last, tr("Cg program objects (*.fpo;*.vpo);;"));
if (file_path.isEmpty())
return;
m_path_last = file_path;
ShowDisasm();
});

Expand All @@ -102,7 +103,7 @@ void cg_disasm_window::ShowContextMenu(const QPoint &pos)
origin = mapToGlobal(pos);
}

myMenu.exec(origin);
menu.exec(origin);
}

void cg_disasm_window::ShowDisasm()
Expand Down
5 changes: 3 additions & 2 deletions rpcs3/rpcs3qt/cg_disasm_window.h
Expand Up @@ -4,6 +4,7 @@

#include <QTextEdit>
#include <QDropEvent>

#include <memory>

class AsmHighlighter;
Expand All @@ -16,14 +17,14 @@ class cg_disasm_window : public QWidget

private Q_SLOTS:
void ShowContextMenu(const QPoint &pos);

private:
void ShowDisasm();
bool IsValidFile(const QMimeData& md, bool save = false);

private:
QString m_path_last;
QTextEdit* m_disasm_text;
QTextEdit* m_glsl_text;
QList<QUrl> m_urls;

QAction *openCgBinaryProgram;

Expand Down
1 change: 1 addition & 0 deletions rpcs3/rpcs3qt/gui_settings.h
Expand Up @@ -129,6 +129,7 @@ namespace gui
const gui_save fd_boot_game = gui_save(main_window, "lastExplorePathGAME", "");
const gui_save fd_decrypt_sprx = gui_save(main_window, "lastExplorePathSPRX", "");
const gui_save fd_cg_disasm = gui_save(main_window, "lastExplorePathCGD", "");
const gui_save fd_log_viewer = gui_save(main_window, "lastExplorePathLOG", "");

const gui_save mw_debugger = gui_save(main_window, "debuggerVisible", false);
const gui_save mw_logger = gui_save(main_window, "loggerVisible", true);
Expand Down
197 changes: 197 additions & 0 deletions rpcs3/rpcs3qt/log_viewer.cpp
@@ -0,0 +1,197 @@
#include "stdafx.h"

#include "log_viewer.h"
#include "gui_settings.h"
#include "syntax_highlighter.h"
#include "find_dialog.h"

#include <QMenu>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QHBoxLayout>
#include <QFontDatabase>
#include <QMimeData>

LOG_CHANNEL(gui_log, "GUI");

constexpr auto qstr = QString::fromStdString;
inline std::string sstr(const QString& _in)
{
return _in.toStdString();
}

log_viewer::log_viewer(std::shared_ptr<gui_settings> settings)
: m_gui_settings(settings)
{
setWindowTitle(tr("Log Viewer"));
setObjectName("log_viewer");
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_StyledBackground);
setAcceptDrops(true);
setMinimumSize(QSize(200, 150)); // seems fine on win 10
resize(QSize(620, 395));

m_path_last = m_gui_settings->GetValue(gui::fd_log_viewer).toString();

m_log_text = new QTextEdit(this);
m_log_text->setReadOnly(true);
m_log_text->setContextMenuPolicy(Qt::CustomContextMenu);
m_log_text->setWordWrapMode(QTextOption::NoWrap);
m_log_text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
m_log_text->installEventFilter(this);

// m_log_text syntax highlighter
m_log_highlighter = new LogHighlighter(m_log_text->document());

QHBoxLayout* layout = new QHBoxLayout();
layout->addWidget(m_log_text);

setLayout(layout);

connect(m_log_text, &QWidget::customContextMenuRequested, this, &log_viewer::show_context_menu);

show_log();
}

void log_viewer::show_context_menu(const QPoint& pos)
{
QMenu menu;
QAction* clear = new QAction(tr("&Clear"));
QAction* open = new QAction(tr("&Open log file"));

menu.addAction(open);
menu.addSeparator();
menu.addAction(clear);

connect(clear, &QAction::triggered, [this]()
{
m_log_text->clear();
});

connect(open, &QAction::triggered, [this]()
{
const QString file_path = QFileDialog::getOpenFileName(this, tr("Select log file"), m_path_last, tr("Log files (*.log);;"));
if (file_path.isEmpty())
return;
m_path_last = file_path;
show_log();
});

const auto obj = qobject_cast<QTextEdit*>(sender());

QPoint origin;

if (obj == m_log_text)
{
origin = m_log_text->viewport()->mapToGlobal(pos);
}
else
{
origin = mapToGlobal(pos);
}

menu.exec(origin);
}

void log_viewer::show_log()
{
if (m_path_last.isEmpty())
{
return;
}

m_log_text->clear();

if (QFile file(m_path_last);
file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text))
{
m_gui_settings->SetValue(gui::fd_log_viewer, m_path_last);

QTextStream stream(&file);

while (!stream.atEnd())
{
m_log_text->append(stream.readLine());
}

file.close();
}
else
{
gui_log.error("log_viewer: Failed to open %s", sstr(m_path_last));
}
}

bool log_viewer::is_valid_file(const QMimeData& md, bool save)
{
const QList<QUrl> urls = md.urls();

if (urls.count() > 1)
{
return false;
}

const QString suffix = QFileInfo(urls[0].fileName()).suffix().toLower();

if (suffix == "log")
{
if (save)
{
m_path_last = urls[0].toLocalFile();
}
return true;
}
return false;
}

void log_viewer::dropEvent(QDropEvent* ev)
{
if (is_valid_file(*ev->mimeData(), true))
{
show_log();
}
}

void log_viewer::dragEnterEvent(QDragEnterEvent* ev)
{
if (is_valid_file(*ev->mimeData()))
{
ev->accept();
}
}

void log_viewer::dragMoveEvent(QDragMoveEvent* ev)
{
if (is_valid_file(*ev->mimeData()))
{
ev->accept();
}
}

void log_viewer::dragLeaveEvent(QDragLeaveEvent* ev)
{
ev->accept();
}

bool log_viewer::eventFilter(QObject* object, QEvent* event)
{
if (object != m_log_text)
{
return QWidget::eventFilter(object, event);
}

if (event->type() == QEvent::KeyPress)
{
QKeyEvent* e = static_cast<QKeyEvent*>(event);
if (e && e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_F)
{
if (m_find_dialog && m_find_dialog->isVisible())
m_find_dialog->close();

m_find_dialog.reset(new find_dialog(static_cast<QTextEdit*>(object), this));
}
}

return QWidget::eventFilter(object, event);
}