From 82f56bfc5a6159be38b942a87db65f2903dbcb93 Mon Sep 17 00:00:00 2001 From: Alex Alabuzhev Date: Mon, 14 Aug 2017 20:43:28 +0000 Subject: [PATCH] FCTL_ETUSERSCREEN available in -e and -v modes --- far/changelog | 4 + far/cmdline.cpp | 177 +------------------------------ far/cmdline.hpp | 17 --- far/console_session.cpp | 223 ++++++++++++++++++++++++++++++++++++++++ far/console_session.hpp | 62 +++++++++++ far/desktop.hpp | 4 + far/far.vcxproj | 2 + far/far.vcxproj.filters | 6 ++ far/filelist.cpp | 3 +- far/interf.cpp | 1 + far/main.cpp | 1 - far/makefile_gcc | 1 + far/makefile_vc | 1 + far/plugapi.cpp | 30 +++--- far/vbuild.m4 | 2 +- 15 files changed, 325 insertions(+), 209 deletions(-) create mode 100644 far/console_session.cpp create mode 100644 far/console_session.hpp diff --git a/far/changelog b/far/changelog index 989ecaec3d..c7f8b8ef5f 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,7 @@ +drkns 14.08.2017 21:38:39 +0000 - build 5006 + +1. Теперь FCTL_ETUSERSCREEN можно использовать и из режимов редактора (-e) и просмотра (-v). + drkns 13.08.2017 17:07:42 +0000 - build 5005 1. Уточнение 4959. diff --git a/far/cmdline.cpp b/far/cmdline.cpp index 5d359a1fe6..09993f0da5 100644 --- a/far/cmdline.cpp +++ b/far/cmdline.cpp @@ -873,120 +873,6 @@ void CommandLine::SetPromptSize(int NewSize) PromptSize = NewSize? std::clamp(NewSize, 5, 95) : DEFAULT_CMDLINE_WIDTH; } -class execution_context: noncopyable, public i_execution_context -{ -public: - void Activate() override - { - if (m_Activated) - return; - - m_Activated = true; - ++Global->SuppressIndicators; - ++Global->SuppressClock; - - Global->WindowManager->ModalDesktopWindow(); - Global->WindowManager->PluginCommit(); - } - - void DrawCommand(const string& Command) override - { - Global->CtrlObject->CmdLine()->DrawFakeCommand(Command); - ScrollScreen(1); - - m_Command = Command; - m_ShowCommand = true; - - DoPrologue(); - } - - void Consolise(bool SetTextColour = true) override - { - assert(m_Activated); - - if (m_Consolised) - return; - m_Consolised = true; - - Global->ScrBuf->MoveCursor(0, WhereY()); - SetInitialCursorType(); - - if (!m_Command.empty()) - ConsoleTitle::SetFarTitle(m_Command); - - // BUGBUG, implement better & safer way to do this - const auto LockCount = Global->ScrBuf->GetLockCount(); - Global->ScrBuf->SetLockCount(0); - - Global->ScrBuf->Flush(); - - // BUGBUG, implement better & safer way to do this - Global->ScrBuf->SetLockCount(LockCount); - - if (SetTextColour) - Console().SetTextAttributes(colors::PaletteColorToFarColor(COL_COMMANDLINEUSERSCREEN)); - } - - void DoPrologue() override - { - Global->CtrlObject->Desktop->TakeSnapshot(); - int X1, Y1, X2, Y2; - Global->CtrlObject->CmdLine()->GetPosition(X1, Y1, X2, Y2); - GotoXY(0, Y1); - m_Finalised = false; - } - - void DoEpilogue() override - { - if (!m_Activated) - return; - - if (m_Finalised) - return; - - if (m_Consolised) - { - if (Global->Opt->ShowKeyBar) - { - Console().Write(L"\n"); - } - Console().Commit(); - Global->ScrBuf->FillBuf(); - - m_Consolised = false; - } - - // Empty command means that user simply pressed Enter in command line, in this case we don't want additional scrolling - // ShowCommand is false when there is no "command" - class instantiated by FCTL_GETUSERSCREEN. - if (!m_Command.empty() || !m_ShowCommand) - { - ScrollScreen(1); - } - - Global->CtrlObject->Desktop->TakeSnapshot(); - - m_Finalised = true; - } - - ~execution_context() override - { - if (!m_Activated) - return; - - Global->WindowManager->UnModalDesktopWindow(); - Global->WindowManager->PluginCommit(); - --Global->SuppressClock; - --Global->SuppressIndicators; - } - -private: - string m_Command; - bool m_ShowCommand{}; - bool m_Activated{}; - bool m_Finalised{}; - bool m_Consolised{}; -}; - static bool ProcessFarCommands(const string& Command, const std::function& ConsoleActivatior) { if (equal_icase(Command, L"far:config"_sv)) @@ -1041,7 +927,7 @@ void CommandLine::ExecString(execute_info& Info) bool Silent = false; bool IsUpdateNeeded = false; - const auto ExecutionContext = GetExecutionContext(); + const auto ExecutionContext = Global->CtrlObject->Desktop->ConsoleSession().GetContext(); SCOPE_EXIT { @@ -1454,64 +1340,3 @@ void CommandLine::LockUpdatePanel(bool Mode) { m_Flags.Change(FCMDOBJ_LOCKUPDATEPANEL,Mode); } - -void CommandLine::EnterPluginExecutionContext() -{ - if (!m_PluginExecutionContextInvocations) - { - m_PluginExecutionContext = GetExecutionContext(); - m_PluginExecutionContext->Activate(); - } - else - { - m_PluginExecutionContext->DoEpilogue(); - } - - m_PluginExecutionContext->DoPrologue(); - m_PluginExecutionContext->Consolise(!m_PluginExecutionContextInvocations); - - ++m_PluginExecutionContextInvocations; -} - -void CommandLine::LeavePluginExecutionContext() -{ - if (m_PluginExecutionContextInvocations) - --m_PluginExecutionContextInvocations; - - if (m_PluginExecutionContext) - { - m_PluginExecutionContext->DoEpilogue(); - } - else - { - // FCTL_SETUSERSCREEN without corresponding FCTL_GETUSERSCREEN - // Old (1.x) behaviour emulation: - if (Global->Opt->ShowKeyBar) - { - Console().Write(L"\n"); - } - Console().Commit(); - Global->ScrBuf->FillBuf(); - ScrollScreen(1); - Global->CtrlObject->Desktop->TakeSnapshot(); - } - - if (m_PluginExecutionContextInvocations) - return; - - m_PluginExecutionContext.reset(); -} - -std::shared_ptr CommandLine::GetExecutionContext() -{ - if (auto Result = m_ExecutionContext.lock()) - { - return Result; - } - else - { - Result = std::make_shared(); - m_ExecutionContext = Result; - return Result; - } -} diff --git a/far/cmdline.hpp b/far/cmdline.hpp index 6309795e26..7a975bc83e 100644 --- a/far/cmdline.hpp +++ b/far/cmdline.hpp @@ -52,17 +52,6 @@ struct execute_info bool RunAs{}; }; -class i_execution_context -{ -public: - virtual void Activate() = 0; - virtual void DrawCommand(const string& Command) = 0; - virtual void DoPrologue() = 0; - virtual void DoEpilogue() = 0; - virtual void Consolise(bool SetTextColour = true) = 0; - virtual ~i_execution_context() = default; -}; - class CommandLine:public SimpleScreenObject { public: @@ -93,9 +82,6 @@ class CommandLine:public SimpleScreenObject int GetPromptSize() const {return PromptSize;} void SetPromptSize(int NewSize); void DrawFakeCommand(const string& FakeCommand); - void EnterPluginExecutionContext(); - void LeavePluginExecutionContext(); - std::shared_ptr GetExecutionContext(); private: virtual void DisplayObject() override; @@ -113,9 +99,6 @@ class CommandLine:public SimpleScreenObject int LastCmdPartLength; string m_CurCmdStr; std::stack ppstack; - std::weak_ptr m_ExecutionContext; - std::shared_ptr m_PluginExecutionContext; - unsigned m_PluginExecutionContextInvocations{}; }; #endif // CMDLINE_HPP_7E68C776_4AA9_4A24_BE9F_7F7FA6D50F30 diff --git a/far/console_session.cpp b/far/console_session.cpp new file mode 100644 index 0000000000..620e8f429d --- /dev/null +++ b/far/console_session.cpp @@ -0,0 +1,223 @@ +/* +console_session.cpp + + +*/ +/* +Copyright © 2017 Far Group +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "headers.hpp" +#pragma hdrstop + +#include "desktop.hpp" +#include "global.hpp" +#include "manager.hpp" +#include "interf.hpp" +#include "config.hpp" +#include "console.hpp" +#include "colormix.hpp" +#include "constitle.hpp" +#include "scrbuf.hpp" +#include "ctrlobj.hpp" +#include "cmdline.hpp" + +class context: noncopyable, public i_context +{ +public: + void Activate() override + { + if (m_Activated) + return; + + m_Activated = true; + ++Global->SuppressIndicators; + ++Global->SuppressClock; + + Global->WindowManager->ModalDesktopWindow(); + Global->WindowManager->PluginCommit(); + } + + void DrawCommand(const string& Command) override + { + Global->CtrlObject->CmdLine()->DrawFakeCommand(Command); + ScrollScreen(1); + + m_Command = Command; + m_ShowCommand = true; + + DoPrologue(); + } + + void Consolise(bool SetTextColour = true) override + { + assert(m_Activated); + + if (m_Consolised) + return; + m_Consolised = true; + + Global->ScrBuf->MoveCursor(0, WhereY()); + SetInitialCursorType(); + + if (!m_Command.empty()) + ConsoleTitle::SetFarTitle(m_Command); + + // BUGBUG, implement better & safer way to do this + const auto LockCount = Global->ScrBuf->GetLockCount(); + Global->ScrBuf->SetLockCount(0); + + Global->ScrBuf->Flush(); + + // BUGBUG, implement better & safer way to do this + Global->ScrBuf->SetLockCount(LockCount); + + if (SetTextColour) + Console().SetTextAttributes(colors::PaletteColorToFarColor(COL_COMMANDLINEUSERSCREEN)); + } + + void DoPrologue() override + { + Global->CtrlObject->Desktop->TakeSnapshot(); + + const auto XPos = 0; + const auto YPos = ScrY - (Global->Opt->ShowKeyBar? 1 : 0); + + GotoXY(XPos, YPos); + m_Finalised = false; + } + + void DoEpilogue() override + { + if (!m_Activated) + return; + + if (m_Finalised) + return; + + if (m_Consolised) + { + if (Global->Opt->ShowKeyBar) + { + Console().Write(L"\n"); + } + Console().Commit(); + Global->ScrBuf->FillBuf(); + + m_Consolised = false; + } + + // Empty command means that user simply pressed Enter in command line, in this case we don't want additional scrolling + // ShowCommand is false when there is no "command" - class instantiated by FCTL_GETUSERSCREEN. + if (!m_Command.empty() || !m_ShowCommand) + { + ScrollScreen(1); + } + + Global->CtrlObject->Desktop->TakeSnapshot(); + + m_Finalised = true; + } + + ~context() override + { + if (!m_Activated) + return; + + Global->WindowManager->UnModalDesktopWindow(); + Global->WindowManager->PluginCommit(); + --Global->SuppressClock; + --Global->SuppressIndicators; + } + +private: + string m_Command; + bool m_ShowCommand{}; + bool m_Activated{}; + bool m_Finalised{}; + bool m_Consolised{}; +}; + +void console_session::EnterPluginContext() +{ + if (!m_PluginContextInvocations) + { + m_PluginContext = GetContext(); + m_PluginContext->Activate(); + } + else + { + m_PluginContext->DoEpilogue(); + } + + m_PluginContext->DoPrologue(); + m_PluginContext->Consolise(!m_PluginContextInvocations); + + ++m_PluginContextInvocations; +} + +void console_session::LeavePluginContext() +{ + if (m_PluginContextInvocations) + --m_PluginContextInvocations; + + if (m_PluginContext) + { + m_PluginContext->DoEpilogue(); + } + else + { + // FCTL_SETUSERSCREEN without corresponding FCTL_GETUSERSCREEN + // Old (1.x) behaviour emulation: + if (Global->Opt->ShowKeyBar) + { + Console().Write(L"\n"); + } + Console().Commit(); + Global->ScrBuf->FillBuf(); + ScrollScreen(1); + Global->CtrlObject->Desktop->TakeSnapshot(); + } + + if (m_PluginContextInvocations) + return; + + m_PluginContext.reset(); +} + +std::shared_ptr console_session::GetContext() +{ + if (auto Result = m_Context.lock()) + { + return Result; + } + else + { + Result = std::make_shared(); + m_Context = Result; + return Result; + } +} diff --git a/far/console_session.hpp b/far/console_session.hpp new file mode 100644 index 0000000000..174aeabde9 --- /dev/null +++ b/far/console_session.hpp @@ -0,0 +1,62 @@ +#ifndef CONSOLE_SESSION_HPP_807900C8_23FD_4505_AEB4_B63E7AF2FF7F +#define CONSOLE_SESSION_HPP_807900C8_23FD_4505_AEB4_B63E7AF2FF7F +#pragma once + +/* +console_session.hpp + + +*/ +/* +Copyright © 2017 Far Group +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +class i_context +{ +public: + virtual void Activate() = 0; + virtual void DrawCommand(const string& Command) = 0; + virtual void DoPrologue() = 0; + virtual void DoEpilogue() = 0; + virtual void Consolise(bool SetTextColour = true) = 0; + virtual ~i_context() = default; +}; + +class console_session +{ +public: + void EnterPluginContext(); + void LeavePluginContext(); + std::shared_ptr GetContext(); + +private: + std::unique_ptr m_Background; + std::weak_ptr m_Context; + std::shared_ptr m_PluginContext; + unsigned m_PluginContextInvocations{}; +}; + +#endif // CONSOLE_SESSION_HPP_807900C8_23FD_4505_AEB4_B63E7AF2FF7F diff --git a/far/desktop.hpp b/far/desktop.hpp index b6fa76ab30..19e168a70f 100644 --- a/far/desktop.hpp +++ b/far/desktop.hpp @@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "window.hpp" +#include "console_session.hpp" class desktop: public window { @@ -51,11 +52,14 @@ class desktop: public window void TakeSnapshot(); + console_session& ConsoleSession() { return m_ConsoleSession; } + private: virtual string GetTitle() const override { return L"Desktop"s; } // TODO: localization virtual void DisplayObject() override; std::unique_ptr m_Background; + console_session m_ConsoleSession; }; #endif // DESKTOP_HPP_16E84F3B_443F_487F_A5E6_FC6432462DB5 diff --git a/far/far.vcxproj b/far/far.vcxproj index 778d6cb807..65852b69c4 100644 --- a/far/far.vcxproj +++ b/far/far.vcxproj @@ -173,6 +173,7 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c + @@ -348,6 +349,7 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c + diff --git a/far/far.vcxproj.filters b/far/far.vcxproj.filters index f34b3c7961..bad4fd7b38 100644 --- a/far/far.vcxproj.filters +++ b/far/far.vcxproj.filters @@ -437,6 +437,9 @@ Source Files + + Source Files + @@ -988,6 +991,9 @@ Header Files + + Header Files + diff --git a/far/filelist.cpp b/far/filelist.cpp index 1c5d6e34f0..61dc5ef837 100644 --- a/far/filelist.cpp +++ b/far/filelist.cpp @@ -95,6 +95,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "vmenu.hpp" #include "vmenu2.hpp" #include "filefilterparams.hpp" +#include "desktop.hpp" static int ListSortGroups,ListSelectedFirst,ListDirectoriesFirst; static panel_sort ListSortMode(panel_sort::UNSORTED); @@ -4934,7 +4935,7 @@ bool FileList::ApplyCommand() GetSelName(nullptr,FileAttr); Parent()->GetCmdLine()->LockUpdatePanel(true); { - const auto ExecutionContext = Parent()->GetCmdLine()->GetExecutionContext(); + const auto ExecutionContext = Global->CtrlObject->Desktop->ConsoleSession().GetContext(); while (GetSelName(&strSelName, FileAttr, &strSelShortName) && !CheckForEsc()) { string strListName, strAnotherListName; diff --git a/far/interf.cpp b/far/interf.cpp index d6fed8fc38..cff7c73c9f 100644 --- a/far/interf.cpp +++ b/far/interf.cpp @@ -362,6 +362,7 @@ void InitConsole(int FirstInit) void CloseConsole() { Global->ScrBuf->Flush(); + MoveRealCursor(0, ScrY); Console().SetCursorInfo(InitialCursorInfo); ChangeConsoleMode(Console().GetInputHandle(), InitialConsoleMode); diff --git a/far/main.cpp b/far/main.cpp index 268b2007e8..d484fefc82 100644 --- a/far/main.cpp +++ b/far/main.cpp @@ -295,7 +295,6 @@ static int MainProcess( Console().SetTextAttributes(InitAttributes); Global->ScrBuf->ResetLockCount(); Global->ScrBuf->Flush(); - MoveRealCursor(0,0); return 0; } diff --git a/far/makefile_gcc b/far/makefile_gcc index 4b35ec015b..92732c7a9e 100644 --- a/far/makefile_gcc +++ b/far/makefile_gcc @@ -31,6 +31,7 @@ SRCS = \ config.cpp \ configdb.cpp \ console.cpp \ + console_session.cpp \ constitle.cpp \ copy.cpp \ copy_progress.cpp \ diff --git a/far/makefile_vc b/far/makefile_vc index 6598cdcdfe..6119d74e79 100644 --- a/far/makefile_vc +++ b/far/makefile_vc @@ -114,6 +114,7 @@ LINK_OBJS = \ "$(INTDIR)\config.obj" \ "$(INTDIR)\configdb.obj" \ "$(INTDIR)\console.obj" \ + "$(INTDIR)\console_session.obj" \ "$(INTDIR)\constitle.obj" \ "$(INTDIR)\copy.obj" \ "$(INTDIR)\copy_progress.obj" \ diff --git a/far/plugapi.cpp b/far/plugapi.cpp index 314e20e2e4..c0b79c4999 100644 --- a/far/plugapi.cpp +++ b/far/plugapi.cpp @@ -85,6 +85,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "string_utils.hpp" #include "cvtname.hpp" #include "filemasks.hpp" +#include "desktop.hpp" static Plugin* GuidToPlugin(const GUID* Id) { @@ -1266,7 +1267,22 @@ intptr_t WINAPI apiPanelControl(HANDLE hPlugin,FILE_CONTROL_COMMANDS Command,int if (Command == FCTL_CHECKPANELSEXIST) return !Global->OnlyEditorViewerUsed; - if (Global->OnlyEditorViewerUsed || !Global->CtrlObject || Global->WindowManager->ManagerIsDown()) + if (!Global->CtrlObject || Global->WindowManager->ManagerIsDown()) + return 0; + + if (Command == FCTL_GETUSERSCREEN) + { + Global->CtrlObject->Desktop->ConsoleSession().EnterPluginContext(); + return TRUE; + } + + if (Command == FCTL_SETUSERSCREEN) + { + Global->CtrlObject->Desktop->ConsoleSession().LeavePluginContext(); + return TRUE; + } + + if (Global->OnlyEditorViewerUsed) return 0; const auto FPanels = Global->CtrlObject->Cp(); @@ -1352,18 +1368,6 @@ intptr_t WINAPI apiPanelControl(HANDLE hPlugin,FILE_CONTROL_COMMANDS Command,int return Processed; } - case FCTL_GETUSERSCREEN: - { - Global->CtrlObject->CmdLine()->EnterPluginExecutionContext(); - return TRUE; - } - - case FCTL_SETUSERSCREEN: - { - Global->CtrlObject->CmdLine()->LeavePluginExecutionContext(); - return TRUE; - } - case FCTL_GETCMDLINE: { const auto& Str = CmdLine->GetString(); diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 8de0d0e858..5e59b92117 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -m4_define(BUILD,5005)m4_dnl +m4_define(BUILD,5006)m4_dnl