<commit_before>﻿#include "orz/stream_file.h"
#include "orz/fileops.h"
#include "orz/intl.h"
#include "orz/sysinfo.h"

#include "imagecache.h"
#include "illa/surfacemgr.h"

//#include "rename.h"

#include "registry.h"

#include "getevent.h"
#include "viewer.h"

#include "config.h"

#include "filterstring.h"
#include "builder_viewport.h"

#include <boost/date_time/c_local_time_adjustor.hpp>
#include <boost/format.hpp>
#include <boost/scoped_array.hpp>
#include <wx/display.h>
#include <wx/msgdlg.h>
#include <wx/filedlg.h>

const wchar_t* App::Viewer::ClassName = L"Pictus Viewer";
const wchar_t* App::Viewer::AppTitle = L"Pictus";

wxDEFINE_EVENT(ImageLoadEvent, wxCommandEvent);

namespace App {
	using namespace Win;
	using namespace Intl;

	using namespace Geom;

	wxBEGIN_EVENT_TABLE(Viewer, wxFrame)
		EVT_LEFT_DOWN(Viewer::OnMouseStandardEvent)
		EVT_LEFT_DCLICK(Viewer::OnMouseDoubleEvent)
		EVT_MIDDLE_DOWN(Viewer::OnMouseStandardEvent)
		EVT_MIDDLE_DCLICK(Viewer::OnMouseDoubleEvent)
		EVT_RIGHT_DOWN(Viewer::OnMouseStandardEvent)
		EVT_RIGHT_DCLICK(Viewer::OnMouseDoubleEvent)
		EVT_MOUSEWHEEL(Viewer::OnMouseStandardEvent)
		EVT_SIZE(Viewer::OnSizeEvent)
		EVT_SIZING(Viewer::OnSizeEvent)
		EVT_MOVE(Viewer::OnMoveEvent)
		EVT_COMMAND(wxID_ANY, ImageLoadEvent, Viewer::OnImageLoadEvent)
	wxEND_EVENT_TABLE()

	void Viewer::OnMouseStandardEvent(wxMouseEvent &e)
	{
		if (!m_mouseMap.Execute(MouseStandardEvent(e, m_cfg.Mouse), e))
		{
			e.ResumePropagation(1);
			e.Skip();
		}
	}

	void Viewer::OnMouseDoubleEvent(wxMouseEvent &e)
	{
		auto ev = MouseDblEvent(e, m_cfg.Mouse);
		if (ev == MouseAction::MouseUndefined || ev == MouseAction::MouseDisable)
		{
			ev = MouseStandardEvent(e, m_cfg.Mouse);
		}

		if (!m_mouseMap.Execute(ev, e))
		{
			e.ResumePropagation(1);
			e.Skip();
		}
	}

	void Viewer::OnSizeEvent(wxSizeEvent &e)
	{
		PerformOnSize(wxToSize(e.GetSize()));
		e.Skip();
	}

	void Viewer::OnImageLoadEvent(wxCommandEvent &e)
	{
		HandleCacheNotification();
	}

	Viewer::Viewer(Img::CodecFactoryStore* cfs, Reg::Settings cfg):
		m_attemptToShow{ false },
		m_screenMode{ SM_Normal },
		m_doMaximize{ false },
		m_viewPort{ this },
		m_statusBar{ nullptr },
		m_codecs{ cfs },
		m_dropTarget{ nullptr },
		m_cfg( cfg )
	{

	}

	Viewer::~Viewer() {
		m_folderMonitor.Close();
		m_cacher.Stop();

		/*if (UnhandledExceptionOcurred()) {
			MessageBox(nullptr, UTF8ToWString(UnhandledExceptionDescription()).c_str(), L"Pictus error", MB_OK);
		}*/
	}

	/*bool Viewer::Show(bool doShow) {
		auto img = m_viewPort.Image();
		auto allocated = IsPositive(m_viewPort.OptimalViewportSize());
		auto defective = img?!img->IsHeaderInformationValid() && img->IsFinished():true;
		ImageChanged();
		if (m_doMaximize == false && !allocated && !defective) {
			m_attemptToShow = doShow;
			return true;
		}

		ShowWindow(Handle(), (doShow ? (m_doMaximize ? SW_MAXIMIZE : SW_SHOW) : SW_HIDE));
		if (doShow) {
			m_doMaximize = false;
		}
		m_attemptToShow = false;
		return true;
	}*/

	Img::Image::Ptr Viewer::ActiveImage() const
	{
		return m_viewPort.Image();
	}

	void Viewer::ActiveImage(Img::Image::Ptr pImage) {
		if (m_viewPort.Image() == pImage) {
			return;
		}

		m_viewPort.Image(pImage);

		if (m_cfg.View.ResetZoom) {
			ZoomMode(m_cfg.View.DefaultZoomMode);
			UpdateImageInformation();
		}
		else {
			ImageChanged();
		}
	}

	void Viewer::CreateWindow()
	{
		auto winSize = wxDefaultSize;
		auto winPos = wxDefaultPosition;

		auto displayIndex = wxDisplay::GetFromPoint({ m_cfg.View.WindowPosX, m_cfg.View.WindowPosY });
		if (displayIndex != wxNOT_FOUND && displayIndex >= 0)
		{
			wxDisplay display(static_cast<unsigned int>(displayIndex));
			auto displayGeometry = display.GetClientArea();

			int w = Util::Constrain<int>(MinWindowWidth, m_cfg.View.WindowSizeWidth, displayGeometry.GetWidth());
			int h = Util::Constrain<int>(MinWindowHeight, m_cfg.View.WindowSizeHeight, displayGeometry.GetHeight());

			int x = Util::Constrain<int>(displayGeometry.GetLeft(), m_cfg.View.WindowPosX, displayGeometry.GetWidth() - w);
			int y = Util::Constrain<int>(displayGeometry.GetRight(), m_cfg.View.WindowPosY, displayGeometry.GetHeight() - h);

			winSize = { w, h };
			winPos = { x, y };
		}

		Create(nullptr, -1, L"Pictus", winPos, winSize, wxDEFAULT_FRAME_STYLE);
	}


	bool Viewer::Init(const std::string params)
	{
		m_dropTarget = new DropTarget(this);
		m_normalRect = wxToRect(GetRect());

		ViewportBuilder b;
		b.BuildViewport(m_viewPort, this, m_cfg);

		//m_adjust.OnChange.connect([this](int a, int b, int c) { AdjustChange(a, b, c); });

		m_mouseMap.AddAction(MouseFullscreen, [this](Win::MouseEvent) { ToggleFullscreenMode(); });
		m_mouseMap.AddAction(MouseToggleFullSizeDefaultZoom, [&](Win::MouseEvent) { ZoomToggleFullSizeDefaultZoom(); });
		m_mouseMap.AddAction(MouseNextImage, [this](Win::MouseEvent) { ImageNext(1); });
		m_mouseMap.AddAction(MousePrevImage, [this](Win::MouseEvent) { ImagePrev(1); });
		m_mouseMap.AddAction(MouseZoomIn, [this](Win::MouseEvent) { ZoomIn(); });
		m_mouseMap.AddAction(MouseZoomOut, [this](Win::MouseEvent) { ZoomOut(); });
		m_mouseMap.AddAction(MouseContext, [this](Win::MouseEvent e) { ShowContextMenu(e); });
		m_mouseMap.AddAction(MouseRotateLeft, [this](Win::MouseEvent) { RotateLeft(); });
		m_mouseMap.AddAction(MouseRotateRight, [this](Win::MouseEvent) { RotateRight(); });

		m_contextMenu.Construct(this);
		m_keys.Construct(this);
		m_keys.SetBindings(m_cfg.Keyboard);

		m_lang = Intl::OnLanguageChanged.connect([&]() { UpdateImageInformation(); });
<commit_msg>Save position of window between launches<commit_after>﻿#include "orz/stream_file.h"
#include "orz/fileops.h"
#include "orz/intl.h"
#include "orz/sysinfo.h"

#include "imagecache.h"
#include "illa/surfacemgr.h"

//#include "rename.h"

#include "registry.h"

#include "getevent.h"
#include "viewer.h"

#include "config.h"

#include "filterstring.h"
#include "builder_viewport.h"

#include <boost/date_time/c_local_time_adjustor.hpp>
#include <boost/format.hpp>
#include <boost/scoped_array.hpp>
#include <wx/display.h>
#include <wx/msgdlg.h>
#include <wx/filedlg.h>

const wchar_t* App::Viewer::ClassName = L"Pictus Viewer";
const wchar_t* App::Viewer::AppTitle = L"Pictus";

wxDEFINE_EVENT(ImageLoadEvent, wxCommandEvent);

namespace App {
	using namespace Win;
	using namespace Intl;

	using namespace Geom;

	wxBEGIN_EVENT_TABLE(Viewer, wxFrame)
		EVT_LEFT_DOWN(Viewer::OnMouseStandardEvent)
		EVT_LEFT_DCLICK(Viewer::OnMouseDoubleEvent)
		EVT_MIDDLE_DOWN(Viewer::OnMouseStandardEvent)
		EVT_MIDDLE_DCLICK(Viewer::OnMouseDoubleEvent)
		EVT_RIGHT_DOWN(Viewer::OnMouseStandardEvent)
		EVT_RIGHT_DCLICK(Viewer::OnMouseDoubleEvent)
		EVT_MOUSEWHEEL(Viewer::OnMouseStandardEvent)
		EVT_SIZE(Viewer::OnSizeEvent)
		EVT_SIZING(Viewer::OnSizeEvent)
		EVT_MOVE(Viewer::OnMoveEvent)
		EVT_COMMAND(wxID_ANY, ImageLoadEvent, Viewer::OnImageLoadEvent)
	wxEND_EVENT_TABLE()

	void Viewer::OnMouseStandardEvent(wxMouseEvent &e)
	{
		if (!m_mouseMap.Execute(MouseStandardEvent(e, m_cfg.Mouse), e))
		{
			e.ResumePropagation(1);
			e.Skip();
		}
	}

	void Viewer::OnMouseDoubleEvent(wxMouseEvent &e)
	{
		auto ev = MouseDblEvent(e, m_cfg.Mouse);
		if (ev == MouseAction::MouseUndefined || ev == MouseAction::MouseDisable)
		{
			ev = MouseStandardEvent(e, m_cfg.Mouse);
		}

		if (!m_mouseMap.Execute(ev, e))
		{
			e.ResumePropagation(1);
			e.Skip();
		}
	}

	void Viewer::OnSizeEvent(wxSizeEvent &e)
	{
		PerformOnSize(wxToSize(e.GetSize()));
		e.Skip();
	}

	void Viewer::OnImageLoadEvent(wxCommandEvent &e)
	{
		HandleCacheNotification();
	}

	Viewer::Viewer(Img::CodecFactoryStore* cfs, Reg::Settings cfg):
		m_attemptToShow{ false },
		m_screenMode{ SM_Normal },
		m_doMaximize{ false },
		m_viewPort{ this },
		m_statusBar{ nullptr },
		m_codecs{ cfs },
		m_dropTarget{ nullptr },
		m_cfg( cfg )
	{

	}

	Viewer::~Viewer() {
		m_folderMonitor.Close();
		m_cacher.Stop();

		/*if (UnhandledExceptionOcurred()) {
			MessageBox(nullptr, UTF8ToWString(UnhandledExceptionDescription()).c_str(), L"Pictus error", MB_OK);
		}*/
	}

	/*bool Viewer::Show(bool doShow) {
		auto img = m_viewPort.Image();
		auto allocated = IsPositive(m_viewPort.OptimalViewportSize());
		auto defective = img?!img->IsHeaderInformationValid() && img->IsFinished():true;
		ImageChanged();
		if (m_doMaximize == false && !allocated && !defective) {
			m_attemptToShow = doShow;
			return true;
		}

		ShowWindow(Handle(), (doShow ? (m_doMaximize ? SW_MAXIMIZE : SW_SHOW) : SW_HIDE));
		if (doShow) {
			m_doMaximize = false;
		}
		m_attemptToShow = false;
		return true;
	}*/

	Img::Image::Ptr Viewer::ActiveImage() const
	{
		return m_viewPort.Image();
	}

	void Viewer::ActiveImage(Img::Image::Ptr pImage) {
		if (m_viewPort.Image() == pImage) {
			return;
		}

		m_viewPort.Image(pImage);

		if (m_cfg.View.ResetZoom) {
			ZoomMode(m_cfg.View.DefaultZoomMode);
			UpdateImageInformation();
		}
		else {
			ImageChanged();
		}
	}

	void Viewer::CreateWindow()
	{
		auto winSize = wxDefaultSize;
		auto winPos = wxDefaultPosition;

		auto displayIndex = wxDisplay::GetFromPoint({ m_cfg.View.WindowPosX, m_cfg.View.WindowPosY });
		if (displayIndex != wxNOT_FOUND && displayIndex >= 0)
		{
			wxDisplay display(static_cast<unsigned int>(displayIndex));
			auto displayGeometry = display.GetClientArea();

			int w = Util::Constrain<int>(MinWindowWidth, m_cfg.View.WindowSizeWidth, displayGeometry.GetWidth());
			int h = Util::Constrain<int>(MinWindowHeight, m_cfg.View.WindowSizeHeight, displayGeometry.GetHeight());

			int x = Util::Constrain<int>(displayGeometry.GetLeft(), m_cfg.View.WindowPosX, displayGeometry.GetRight() - w);
			int y = Util::Constrain<int>(displayGeometry.GetTop(), m_cfg.View.WindowPosY, displayGeometry.GetBottom() - h);

			winSize = { w, h };
			winPos = { x, y };
		}

		Create(nullptr, -1, L"Pictus", winPos, winSize, wxDEFAULT_FRAME_STYLE);
	}


	bool Viewer::Init(const std::string params)
	{
		m_dropTarget = new DropTarget(this);
		m_normalRect = wxToRect(GetRect());

		Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& evt) { PerformOnClose(); evt.Skip(); });

		ViewportBuilder b;
		b.BuildViewport(m_viewPort, this, m_cfg);

		//m_adjust.OnChange.connect([this](int a, int b, int c) { AdjustChange(a, b, c); });

		m_mouseMap.AddAction(MouseFullscreen, [this](Win::MouseEvent) { ToggleFullscreenMode(); });
		m_mouseMap.AddAction(MouseToggleFullSizeDefaultZoom, [&](Win::MouseEvent) { ZoomToggleFullSizeDefaultZoom(); });
		m_mouseMap.AddAction(MouseNextImage, [this](Win::MouseEvent) { ImageNext(1); });
		m_mouseMap.AddAction(MousePrevImage, [this](Win::MouseEvent) { ImagePrev(1); });
		m_mouseMap.AddAction(MouseZoomIn, [this](Win::MouseEvent) { ZoomIn(); });
		m_mouseMap.AddAction(MouseZoomOut, [this](Win::MouseEvent) { ZoomOut(); });
		m_mouseMap.AddAction(MouseContext, [this](Win::MouseEvent e) { ShowContextMenu(e); });
		m_mouseMap.AddAction(MouseRotateLeft, [this](Win::MouseEvent) { RotateLeft(); });
		m_mouseMap.AddAction(MouseRotateRight, [this](Win::MouseEvent) { RotateRight(); });

		m_contextMenu.Construct(this);
		m_keys.Construct(this);
		m_keys.SetBindings(m_cfg.Keyboard);

		m_lang = Intl::OnLanguageChanged.connect([&]() { UpdateImageInformation(); });

{'fraction_non_alphanumeric': 0.1514855008005693, 'fraction_numerical': 0.0012453300124533001, 'mean_word_length': 5.688280785246877, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4299328', 'n_tokens_mistral': 4493, 'n_tokens_neox': 4167, 'n_words': 640}