Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/elfmz/far2l.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelfmz <fenix1905@tut.by>2021-12-31 00:27:16 +0300
committerelfmz <fenix1905@tut.by>2021-12-31 02:27:02 +0300
commita14dc1a81c797928d4f1b7d6a6b46ecc63f98308 (patch)
treec27c61ac33582bc4d469c6608cd042add388f230 /far2l/src/panel.cpp
parentd5f1bf245e96834d44390d1723cfef3dfbb1fb02 (diff)
shuffle a bit far2l sources
Diffstat (limited to 'far2l/src/panel.cpp')
-rw-r--r--far2l/src/panel.cpp2279
1 files changed, 2279 insertions, 0 deletions
diff --git a/far2l/src/panel.cpp b/far2l/src/panel.cpp
new file mode 100644
index 00000000..1ec551fe
--- /dev/null
+++ b/far2l/src/panel.cpp
@@ -0,0 +1,2279 @@
+/*
+panel.cpp
+
+Parent class для панелей
+*/
+/*
+Copyright (c) 1996 Eugene Roshal
+Copyright (c) 2000 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"
+
+
+#include "panel.hpp"
+#include "macroopcode.hpp"
+#include "keyboard.hpp"
+#include "lang.hpp"
+#include "keys.hpp"
+#include "vmenu.hpp"
+#include "filepanels.hpp"
+#include "cmdline.hpp"
+#include "chgmmode.hpp"
+#include "chgprior.hpp"
+#include "edit.hpp"
+#include "treelist.hpp"
+#include "filelist.hpp"
+#include "dialog.hpp"
+#include "savescr.hpp"
+#include "manager.hpp"
+#include "ctrlobj.hpp"
+#include "scrbuf.hpp"
+#include "array.hpp"
+#include "lockscrn.hpp"
+#include "help.hpp"
+#include "syslog.hpp"
+#include "plugapi.hpp"
+#include "cddrv.hpp"
+#include "interf.hpp"
+#include "message.hpp"
+#include "Mounts.hpp"
+#include "clipboard.hpp"
+#include "config.hpp"
+#include "scrsaver.hpp"
+#include "execute.hpp"
+#include "Bookmarks.hpp"
+#include "options.hpp"
+#include "pathmix.hpp"
+#include "dirmix.hpp"
+#include "constitle.hpp"
+#include "FarDlgBuilder.hpp"
+#include "setattr.hpp"
+#include "palette.hpp"
+#include "panel.hpp"
+#include "drivemix.hpp"
+
+static int DragX,DragY,DragMove;
+static Panel *SrcDragPanel;
+static SaveScreen *DragSaveScr=nullptr;
+static FARString strDragName;
+
+/* $ 21.08.2002 IS
+ Класс для хранения пункта плагина в меню выбора дисков
+*/
+class ChDiskPluginItem
+{
+ public:
+ MenuItemEx Item;
+ WCHAR HotKey;
+
+ ChDiskPluginItem() { Clear(); }
+ ~ChDiskPluginItem() {}
+
+ void Clear() { HotKey = 0; Item.Clear(); }
+ bool operator==(const ChDiskPluginItem &rhs) const { return HotKey==rhs.HotKey && !StrCmpI(Item.strName,rhs.Item.strName) && Item.UserData==rhs.Item.UserData; }
+ int operator<(const ChDiskPluginItem &rhs) const {return StrCmpI(Item.strName,rhs.Item.strName)<0;}
+ const ChDiskPluginItem& operator=(const ChDiskPluginItem &rhs);
+};
+
+const ChDiskPluginItem& ChDiskPluginItem::operator=(const ChDiskPluginItem &rhs)
+{
+ if (this != &rhs)
+ {
+ Item=rhs.Item;
+ HotKey=rhs.HotKey;
+ }
+
+ return *this;
+}
+
+
+Panel::Panel():
+ Focus(0),
+ EnableUpdate(TRUE),
+ PanelMode(NORMAL_PANEL),
+ PrevViewMode(VIEW_3),
+ NumericSort(0),
+ CaseSensitiveSort(0),
+ DirectoriesFirst(1),
+ ModalMode(0),
+ ViewSettings(),
+ ProcessingPluginCommand(0)
+{
+ _OT(SysLog(L"[%p] Panel::Panel()", this));
+ SrcDragPanel=nullptr;
+ DragX=DragY=-1;
+};
+
+
+Panel::~Panel()
+{
+ _OT(SysLog(L"[%p] Panel::~Panel()", this));
+ EndDrag();
+}
+
+
+void Panel::SetViewMode(int ViewMode)
+{
+ PrevViewMode=ViewMode;
+ Panel::ViewMode=ViewMode;
+};
+
+
+void Panel::ChangeDirToCurrent()
+{
+ FARString strNewDir;
+ apiGetCurrentDirectory(strNewDir);
+ SetCurDir(strNewDir,TRUE);
+}
+
+
+void Panel::ChangeDisk()
+{
+ int Pos=0,FirstCall=TRUE;
+
+ if (!strCurDir.IsEmpty() && strCurDir.At(1)==L':')
+ {
+ Pos=Upper(strCurDir.At(0))-L'A';
+ }
+
+ while (Pos!=-1)
+ {
+ Pos=ChangeDiskMenu(Pos,FirstCall);
+ FirstCall=FALSE;
+ }
+}
+
+
+struct PanelMenuItem
+{
+ enum Kind
+ {
+ UNSPECIFIED = 0,
+ MOUNTPOINT,
+ DIRECTORY,
+ SHORTCUT,
+ PLUGIN,
+ } kind = UNSPECIFIED;
+
+ Plugin *pPlugin = nullptr;
+
+ INT_PTR nItem = -1; // plugin item or shortcut index
+
+ struct {
+ wchar_t path[0x1000];
+ int id;
+ } location;
+};
+
+static void AddPluginItems(VMenu &ChDisk, int Pos)
+{
+ TArray<ChDiskPluginItem> MPItems;
+ ChDiskPluginItem OneItem;
+ // Список дополнительных хоткеев, для случая, когда плагинов, добавляющих пункт в меню, больше 9.
+ int PluginItem, PluginNumber = 0; // IS: счетчики - плагинов и пунктов плагина
+ bool ItemPresent,Done=false;
+ FARString strMenuText;
+ FARString strPluginText;
+
+ while (!Done)
+ {
+ for (PluginItem=0;; ++PluginItem)
+ {
+ if (PluginNumber >= CtrlObject->Plugins.GetPluginsCount())
+ {
+ Done=true;
+ break;
+ }
+
+ Plugin *pPlugin = CtrlObject->Plugins.GetPlugin(PluginNumber);
+
+ WCHAR HotKey = 0;
+ if (!CtrlObject->Plugins.GetDiskMenuItem(
+ pPlugin,
+ PluginItem,
+ ItemPresent,
+ HotKey,
+ strPluginText
+ ))
+ {
+ Done=true;
+ break;
+ }
+
+ if (!ItemPresent)
+ break;
+
+ strMenuText = strPluginText;
+
+ if (!strMenuText.IsEmpty())
+ {
+ OneItem.Clear();
+ PanelMenuItem *item = new PanelMenuItem;
+ item->kind = PanelMenuItem::PLUGIN;
+ item->pPlugin = pPlugin;
+ item->nItem = PluginItem;
+
+ if (pPlugin->IsOemPlugin())
+ OneItem.Item.Flags=LIF_CHECKED|L'A';
+
+ OneItem.Item.strName = strMenuText;
+ OneItem.Item.UserDataSize=sizeof(PanelMenuItem);
+ OneItem.Item.UserData=(char*)item;
+ OneItem.HotKey=HotKey;
+ ChDiskPluginItem *pResult = MPItems.addItem(OneItem);
+
+ if (pResult)
+ {
+ pResult->Item.UserData = (char*)item; //BUGBUG, это фантастика просто. Исправить!!!! связано с работой TArray
+ pResult->Item.UserDataSize = sizeof(PanelMenuItem);
+ }
+
+ /*
+ else BUGBUG, а вот это, похоже, лишнее
+ {
+ Done=TRUE;
+ break;
+ }
+ */
+ }
+ } // END: for (PluginItem=0;;++PluginItem)
+
+ ++PluginNumber;
+ }
+
+ MPItems.Sort();
+ MPItems.Pack(); // выкинем дубли
+ size_t PluginMenuItemsCount=MPItems.getSize();
+
+ if (PluginMenuItemsCount)
+ {
+ MenuItemEx ChDiskItem;
+
+ ChDiskItem.Clear();
+ ChDiskItem.strName = MSG(MPluginsTitle);
+ ChDiskItem.Flags|=LIF_SEPARATOR;
+ ChDiskItem.UserDataSize=0;
+ ChDisk.AddItem(&ChDiskItem);
+ ChDiskItem.Flags&=~LIF_SEPARATOR;
+
+ for (size_t I=0; I < PluginMenuItemsCount; ++I)
+ {
+ MPItems.getItem(I)->Item.SetSelect(ChDisk.GetItemCount() == Pos);
+ const wchar_t HotKeyStr[]={MPItems.getItem(I)->HotKey?L'&':L' ',MPItems.getItem(I)->HotKey?MPItems.getItem(I)->HotKey:L' ',L' ',MPItems.getItem(I)->HotKey?L' ':L'\0',L'\0'};
+ MPItems.getItem(I)->Item.strName = FARString(HotKeyStr) + MPItems.getItem(I)->Item.strName;
+ ChDisk.AddItem(&MPItems.getItem(I)->Item);
+
+ delete(PanelMenuItem*)MPItems.getItem(I)->Item.UserData; //ммда...
+ }
+ }
+}
+
+static void ConfigureChangeDriveMode()
+{
+ DialogBuilder Builder(MChangeDriveConfigure, L"");
+// Builder.AddCheckbox(MChangeDriveShowDiskType, &Opt.ChangeDriveMode, DRIVE_SHOW_TYPE);
+// Builder.AddCheckbox(MChangeDriveShowNetworkName, &Opt.ChangeDriveMode, DRIVE_SHOW_NETNAME);
+// Builder.AddCheckbox(MChangeDriveShowLabel, &Opt.ChangeDriveMode, DRIVE_SHOW_LABEL);
+// Builder.AddCheckbox(MChangeDriveShowFileSystem, &Opt.ChangeDriveMode, DRIVE_SHOW_FILESYSTEM);
+
+// BOOL ShowSizeAny = Opt.ChangeDriveMode & (DRIVE_SHOW_SIZE | DRIVE_SHOW_SIZE_FLOAT);
+
+// DialogItemEx *ShowSize = Builder.AddCheckbox(MChangeDriveShowSize, &ShowSizeAny);
+// DialogItemEx *ShowSizeFloat = Builder.AddCheckbox(MChangeDriveShowSizeFloat, &Opt.ChangeDriveMode, DRIVE_SHOW_SIZE_FLOAT);
+// ShowSizeFloat->Indent(3);
+// Builder.LinkFlags(ShowSize, ShowSizeFloat, DIF_DISABLE);
+
+ Builder.AddCheckbox(MChangeDriveShowShortcuts, &Opt.ChangeDriveMode, DRIVE_SHOW_BOOKMARKS);
+ Builder.AddCheckbox(MChangeDriveShowPlugins, &Opt.ChangeDriveMode, DRIVE_SHOW_PLUGINS);
+// Builder.AddCheckbox(MChangeDriveShowCD, &Opt.ChangeDriveMode, DRIVE_SHOW_CDROM);
+// Builder.AddCheckbox(MChangeDriveShowNetworkDrive, &Opt.ChangeDriveMode, DRIVE_SHOW_REMOTE);
+
+ Builder.AddOKCancel();
+ if (Builder.ShowDialog())
+ {
+// if (ShowSizeAny)
+// {
+// bool ShowSizeFloat = (Opt.ChangeDriveMode & DRIVE_SHOW_SIZE_FLOAT) ? true : false;
+// if (ShowSizeFloat)
+// Opt.ChangeDriveMode &= ~DRIVE_SHOW_SIZE;
+// else
+// Opt.ChangeDriveMode |= DRIVE_SHOW_SIZE;
+// }
+// else
+// Opt.ChangeDriveMode &= ~(DRIVE_SHOW_SIZE | DRIVE_SHOW_SIZE_FLOAT);
+ }
+}
+
+
+LONG_PTR WINAPI ChDiskDlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2)
+{
+ switch (Msg)
+ {
+ case DN_CTLCOLORDLGITEM:
+ {
+ if (Param1 == 1) // BUGBUG, magic number
+ {
+ int Color=FarColorToReal(COL_WARNDIALOGTEXT);
+ return ((Param2&0xFF00FF00)|(Color<<16)|Color);
+ }
+ }
+ break;
+ }
+ return DefDlgProc(hDlg,Msg,Param1,Param2);
+}
+
+static void AddBookmarkItems(VMenu &ChDisk, int Pos)
+{
+ Bookmarks b;
+ for (int SCPos = 0, AddedCount = 0;; ++SCPos)
+ {
+ FARString Folder, Plugin, PluginFile, ShortcutPath;
+ if (b.Get(SCPos, &Folder, &Plugin, &PluginFile, nullptr))
+ {
+ MenuItemEx ChDiskItem;
+
+ if (!AddedCount++)
+ {
+ ChDiskItem.Clear();
+ ChDiskItem.strName = MSG(MBookmarksTitle);
+ ChDiskItem.Flags|= LIF_SEPARATOR;
+ ChDiskItem.UserDataSize=0;
+ ChDisk.AddItem(&ChDiskItem);
+ ChDiskItem.Flags&= ~LIF_SEPARATOR;
+ }
+
+ ChDiskItem.Clear();
+ ChDiskItem.SetSelect(ChDisk.GetItemCount() == Pos);
+
+ if (!PluginFile.IsEmpty())
+ {
+ ShortcutPath+= PluginFile;
+ ShortcutPath+= L"/";
+ }
+ ShortcutPath+= Folder;
+ if (ShortcutPath.IsEmpty())
+ {
+ ShortcutPath = L"@";
+ ShortcutPath+= Plugin;
+ }
+
+ if (SCPos <= 9)
+ ChDiskItem.strName.Format(L"&%d ", SCPos);
+ else
+ ChDiskItem.strName = L" ";
+
+ ChDiskItem.strName+= TruncPathStr(ShortcutPath, 64);
+
+ PanelMenuItem item;
+ item.kind = PanelMenuItem::SHORTCUT;
+ item.nItem = SCPos;
+ ChDisk.SetUserData(&item, sizeof(item), ChDisk.AddItem(&ChDiskItem));
+ }
+ else if (SCPos > 10)
+ {
+ break;
+ }
+ }
+}
+
+int Panel::ChangeDiskMenu(int Pos,int FirstCall)
+{
+ /*Events.DeviceArivalEvent.Reset();
+ Events.DeviceRemoveEvent.Reset();
+ Events.MediaArivalEvent.Reset();
+ Events.MediaRemoveEvent.Reset();*/
+ class Guard_Macro_DskShowPosType //фигня какая-то
+ {
+ public:
+ Guard_Macro_DskShowPosType(Panel *curPanel) {Macro_DskShowPosType=(curPanel==CtrlObject->Cp()->LeftPanel)?1:2;};
+ ~Guard_Macro_DskShowPosType() {Macro_DskShowPosType=0;};
+ };
+ Guard_Macro_DskShowPosType _guard_Macro_DskShowPosType(this);
+ MenuItemEx ChDiskItem;
+ FARString strDiskType, strRootDir, strDiskLetter;
+
+ FARString curdir, another_curdir;
+ GetCurDir(curdir);
+
+ auto another_panel = CtrlObject->Cp()->GetAnotherPanel(this);
+ another_panel->GetCurDirPluginAware(another_curdir);
+ if (another_panel->GetPluginHandle() != INVALID_HANDLE_VALUE)
+ {
+ another_curdir.Insert(0, L"{");
+ another_curdir.Append(L"}");
+ }
+
+ PanelMenuItem Item, *mitem=0;
+ { // эта скобка надо, см. M#605
+ VMenu ChDisk(MSG(MChangeDriveTitle),nullptr,0,ScrY-Y1-3);
+ ChDisk.SetBottomTitle(MSG(MChangeDriveMenuFooter));
+ ChDisk.SetFlags(VMENU_NOTCENTER);
+
+ if (this == CtrlObject->Cp()->LeftPanel)
+ ChDisk.SetFlags(VMENU_LEFTMOST);
+
+ ChDisk.SetHelp(L"DriveDlg");
+ ChDisk.SetFlags(VMENU_WRAPMODE);
+ Mounts::Enum mounts(another_curdir);
+ for (const auto &m : mounts) {
+ ChDiskItem.Clear();
+
+ if (m.path == L"-" ) {
+ ChDiskItem.strName = m.info;
+ ChDiskItem.Flags|= LIF_SEPARATOR;
+ ChDisk.AddItem(&ChDiskItem);
+ ChDiskItem.Flags&= ~LIF_SEPARATOR;
+
+ } else {
+ ChDiskItem.SetSelect(ChDisk.GetItemCount() == Pos);
+ const wchar_t HotKeyStr[] = {m.hotkey ? L'&' : L' ', m.hotkey ? m.hotkey : L' ', m.hotkey ? L' ' : 0, 0};
+ ChDiskItem.strName = HotKeyStr;
+ ChDiskItem.strName+= FixedSizeStr(m.path, std::min(mounts.max_path, (size_t)48), true);
+ if (mounts.max_usage)
+ {
+ ChDiskItem.strName+= L' ';
+ ChDiskItem.strName+= BoxSymbols[BS_V1];
+ ChDiskItem.strName+= L' ';
+ ChDiskItem.strName+= FixedSizeStr(m.usage, std::min(mounts.max_usage, (size_t)24), false);
+ }
+ ChDiskItem.strName+= L' ';
+ ChDiskItem.strName+= BoxSymbols[BS_V1];
+ ChDiskItem.strName+= L' ';
+ ChDiskItem.strName+= FixedSizeStr(m.info, std::min(mounts.max_info, (size_t)24), false);
+
+ PanelMenuItem item;
+ wcsncpy(item.location.path, m.path.CPtr(), ARRAYSIZE(item.location.path) - 1);
+ item.location.id = m.id;
+ if (item.location.path[0] == L'{' && another_curdir == item.location.path
+ && another_panel->GetPluginHandle() != INVALID_HANDLE_VALUE)
+ {
+ item.kind = PanelMenuItem::PLUGIN;
+ item.pPlugin = nullptr;
+ }
+ else
+ item.kind = m.unmountable ? PanelMenuItem::MOUNTPOINT : PanelMenuItem::DIRECTORY;
+
+ ChDisk.SetUserData(&item, sizeof(item), ChDisk.AddItem(&ChDiskItem));
+ }
+ }
+
+ if (Opt.ChangeDriveMode & DRIVE_SHOW_BOOKMARKS)
+ {
+ AddBookmarkItems(ChDisk, Pos);
+ }
+
+ if (Opt.ChangeDriveMode & DRIVE_SHOW_PLUGINS)
+ {
+ AddPluginItems(ChDisk, Pos);
+ }
+
+ Pos = 0;
+
+ int X=X1+5;
+
+ if ((this == CtrlObject->Cp()->RightPanel) && IsFullScreen() && (X2-X1 > 40))
+ X = (X2-X1+1)/2+5;
+
+ int Y = (ScrY + 1 - (ChDisk.GetItemCount() + 5)) / 2;
+
+ if (Y < 1)
+ Y=1;
+
+ ChDisk.SetPosition(X,Y,0,0);
+
+ if (Y < 3)
+ ChDisk.SetBoxType(SHORT_DOUBLE_BOX);
+
+ ChDisk.Show();
+
+ while (!ChDisk.Done())
+ {
+ int Key;
+ /*if(Events.DeviceArivalEvent.Signaled() || Events.DeviceRemoveEvent.Signaled() || Events.MediaArivalEvent.Signaled() || Events.MediaRemoveEvent.Signaled())
+ {
+ Key=KEY_CTRLR;
+ }
+ else*/
+ {
+ { //очередная фигня
+ ChangeMacroMode MacroMode(MACRO_DISKS);
+ Key=ChDisk.ReadInput();
+ }
+ }
+ int SelPos=ChDisk.GetSelectPos();
+ PanelMenuItem *item = (PanelMenuItem*)ChDisk.GetUserData(nullptr,0);
+
+ switch (Key)
+ {
+ // Shift-Enter в меню выбора дисков вызывает проводник для данного диска
+ case KEY_SHIFTNUMENTER:
+ case KEY_SHIFTENTER:
+ {
+ if (item && !item->pPlugin)
+ {
+ Execute(item->location.path,TRUE,TRUE);
+ }
+ }
+ break;
+ case KEY_CTRLPGUP:
+ case KEY_CTRLNUMPAD9:
+ {
+ if (Opt.PgUpChangeDisk)
+ return -1;
+ }
+ break;
+ case KEY_INS:
+ case KEY_NUMPAD0:
+ {
+// if (item && item->kind == PanelMenuItem::SHORTCUT)
+// {
+// SaveShortcutFolder(item->nItem);
+// }
+// else
+ {
+ ShowBookmarksMenu();
+ }
+ return SelPos;
+ }
+ break;
+ case KEY_CTRLA:
+ case KEY_F4:
+ {
+ if (item)
+ {
+ if (item->kind == PanelMenuItem::PLUGIN)
+ {
+ if (item->pPlugin)
+ {
+ FARString strName = ChDisk.GetItemPtr(SelPos)->strName.SubStr(3);
+ RemoveExternalSpaces(strName);
+
+ if (CtrlObject->Plugins.SetHotKeyDialog(strName,
+ CtrlObject->Plugins.GetHotKeySettingName(item->pPlugin, item->nItem, "DriveMenuHotkey")))
+ {
+ return SelPos;
+ }
+ }
+ }
+ else if (item->kind == PanelMenuItem::SHORTCUT)
+ {
+ ShowBookmarksMenu(item->nItem);
+ return SelPos;
+ }
+ else
+ {
+ Mounts::EditHotkey(item->location.path, item->location.id);
+ return SelPos;
+ }
+ }
+ break;
+ }
+ case KEY_NUMDEL:
+ case KEY_DEL:
+
+ case KEY_SHIFTNUMDEL:
+ case KEY_SHIFTDECIMAL:
+ case KEY_SHIFTDEL:
+ {
+ if (item) switch (item->kind)
+ {
+ case PanelMenuItem::MOUNTPOINT: {
+ FARString path(item->location.path);
+ Mounts::Unmount(path,
+ Key == KEY_SHIFTNUMDEL || Key == KEY_SHIFTDECIMAL || Key == KEY_SHIFTDEL);
+ return SelPos;
+ }
+
+ case PanelMenuItem::SHORTCUT: {
+ Bookmarks().Clear(item->nItem);
+ return SelPos;
+ }
+
+ default: ;
+ }
+ }
+ break;
+ case KEY_CTRL1:
+ case KEY_RCTRL1:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_TYPE;
+ return SelPos ;
+ case KEY_CTRL2:
+ case KEY_RCTRL2:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_NETNAME;
+ return SelPos;
+ case KEY_CTRL3:
+ case KEY_RCTRL3:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_LABEL;
+ return SelPos;
+ case KEY_CTRL4:
+ case KEY_RCTRL4:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_FILESYSTEM;
+ return SelPos;
+ case KEY_CTRL5:
+ case KEY_RCTRL5:
+ {
+ if (Opt.ChangeDriveMode & DRIVE_SHOW_SIZE)
+ {
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_SIZE;
+ Opt.ChangeDriveMode |= DRIVE_SHOW_SIZE_FLOAT;
+ }
+ else
+ {
+ if (Opt.ChangeDriveMode & DRIVE_SHOW_SIZE_FLOAT)
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_SIZE_FLOAT;
+ else
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_SIZE;
+ }
+
+ return SelPos;
+ }
+ case KEY_CTRL6:
+ case KEY_RCTRL6:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_REMOVABLE;
+ return SelPos;
+ case KEY_CTRL7:
+ case KEY_RCTRL7:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_PLUGINS;
+ return SelPos;
+ case KEY_CTRL8:
+ case KEY_RCTRL8:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_BOOKMARKS;
+ return SelPos;
+ case KEY_CTRL9:
+ case KEY_RCTRL9:
+ Opt.ChangeDriveMode ^= DRIVE_SHOW_REMOTE;
+ return SelPos;
+ case KEY_F9:
+ ConfigureChangeDriveMode();
+ return SelPos;
+ case KEY_SHIFTF1:
+ {
+ if (item && item->pPlugin)
+ {
+ // Вызываем нужный топик, который передали в CommandsMenu()
+ FarShowHelp(
+ item->pPlugin->GetModuleName(),
+ nullptr,
+ FHELP_SELFHELP|FHELP_NOSHOWERROR|FHELP_USECONTENTS
+ );
+ }
+
+ break;
+ }
+ case KEY_ALTSHIFTF9:
+
+ if (Opt.ChangeDriveMode&DRIVE_SHOW_PLUGINS)
+ {
+ ChDisk.Hide();
+ CtrlObject->Plugins.Configure();
+ }
+
+ return SelPos;
+ case KEY_SHIFTF9:
+
+ if (item && item->pPlugin && item->pPlugin->HasConfigure())
+ CtrlObject->Plugins.ConfigureCurrent(item->pPlugin, item->nItem);
+
+ return SelPos;
+ case KEY_CTRLR:
+ return SelPos;
+ default:
+ ChDisk.ProcessInput();
+ break;
+ }
+
+ if (ChDisk.Done() &&
+ (ChDisk.Modal::GetExitCode() < 0) &&
+ !strCurDir.IsEmpty() &&
+ (StrCmpN(strCurDir,L"//",2) ))
+ {
+ const wchar_t RootDir[4] = {strCurDir.At(0),L':',GOOD_SLASH,L'\0'};
+
+ if (FAR_GetDriveType(RootDir) == DRIVE_NO_ROOT_DIR)
+ ChDisk.ClearDone();
+ }
+ } // while (!Done)
+
+ if (ChDisk.Modal::GetExitCode()<0)
+ return -1;
+
+ mitem=(PanelMenuItem*)ChDisk.GetUserData(nullptr,0);
+
+ if (mitem)
+ {
+ Item=*mitem;
+ mitem=&Item;
+ }
+ } // эта скобка надо, см. M#605
+
+
+
+ if (ProcessPluginEvent(FE_CLOSE,nullptr))
+ return -1;
+
+ ScrBuf.Flush();
+ INPUT_RECORD rec;
+ PeekInputRecord(&rec);
+
+ if (!mitem)
+ return -1; //???
+
+ if (mitem->kind == PanelMenuItem::PLUGIN)
+ {
+// fprintf(stderr, "pPlugin=%p nItem=0x%lx\n", mitem->pPlugin, (unsigned long)mitem->nItem);
+ LONG_PTR nItem = mitem->nItem;
+ //if (nItem == (LONG_PTR)-1)
+ // nItem = (LONG_PTR)mitem->root;
+
+ if (mitem->pPlugin == nullptr) {
+ // duplicate plugin instance of passive panel
+ auto plugin_name = CtrlObject->Plugins.GetPluginModuleName(another_panel->GetPluginHandle());
+ if (!plugin_name.IsEmpty()) {
+ auto pPlugin = CtrlObject->Plugins.GetPlugin(plugin_name);
+ if (pPlugin) {
+ OpenPluginInfo opi = {sizeof(OpenPluginInfo), 0};
+ CtrlObject->Plugins.GetOpenPluginInfo(another_panel->GetPluginHandle(), &opi);
+
+ std::wstring hostFile, curDir;
+
+ if (opi.CurDir)
+ curDir = opi.CurDir;
+ if (opi.HostFile)
+ hostFile = opi.HostFile;
+
+ SetLocation_Plugin(!hostFile.empty(), pPlugin, curDir.c_str(),
+ hostFile.empty() ? nullptr : hostFile.c_str(), 0);
+ }
+ }
+
+ } else {
+ SetLocation_Plugin(false, mitem->pPlugin, nullptr, nullptr, nItem);
+ }
+ }
+ else if (mitem->kind == PanelMenuItem::SHORTCUT)
+ {
+ ExecShortcutFolder(mitem->nItem);
+ }
+ else if (mitem->kind == PanelMenuItem::MOUNTPOINT || mitem->kind == PanelMenuItem::DIRECTORY)
+ {
+ SetLocation_Directory(mitem->location.path);
+ }
+
+ return -1;
+}
+
+bool Panel::SetLocation_Plugin(bool file_plugin, Plugin *plugin, const wchar_t *path, const wchar_t *host_file, LONG_PTR item)
+{
+ HANDLE hPlugin;
+
+ if (file_plugin)
+ {
+ hPlugin = CtrlObject->Plugins.OpenFilePlugin(host_file, 0, OFP_ALTERNATIVE, plugin);//OFP_NORMAL
+ }
+ else
+ {
+ hPlugin = CtrlObject->Plugins.OpenPlugin( plugin, OPEN_DISKMENU, item); //nItem
+ }
+
+ if (hPlugin == INVALID_HANDLE_VALUE)
+ {
+ fprintf(stderr,
+ "SetLocation_Plugin(%d, %p, '%ls', '%ls', %lld) FAILED plugin open\n",
+ file_plugin, plugin, path, host_file, (long long)item);
+ return false;
+ }
+
+ int Focus = GetFocus();
+ Panel *NewPanel = CtrlObject->Cp()->ChangePanel(this,FILE_PANEL,TRUE,TRUE);
+ NewPanel->SetPluginMode(hPlugin,L"",Focus || !CtrlObject->Cp()->GetAnotherPanel(NewPanel)->IsVisible());
+
+ if (path)
+ {
+ NewPanel->Update(0);
+ NewPanel->Show();
+ CtrlObject->Plugins.SetDirectory(hPlugin, L"/", 0);
+ if (!CtrlObject->Plugins.SetDirectory(hPlugin, path, 0))
+ {
+ fprintf(stderr,
+ "SetLocation_Plugin(%d, %p, '%ls', '%ls', %lld) FAILED set directory\n",
+ file_plugin, plugin, path, host_file, (long long)item);
+ }
+ }
+
+ NewPanel->Update(0);
+ NewPanel->Show();
+
+ if (!Focus && CtrlObject->Cp()->GetAnotherPanel(this)->GetType() == INFO_PANEL)
+ {
+ CtrlObject->Cp()->GetAnotherPanel(this)->UpdateKeyBar();
+ }
+
+ return true;
+}
+
+bool Panel::SetLocation_Directory(const wchar_t *path)
+{
+ if (!FarChDir(path))
+ {
+ if (CtrlObject->Plugins.ProcessCommandLine(path))
+ {
+ fprintf(stderr, "SetLocation_Directory('%ls') PLUGIN\n", path);
+ return true;
+ }
+
+ fprintf(stderr, "SetLocation_Directory('%ls') FAILED\n", path);
+ return false;
+ }
+
+ fprintf(stderr, "SetLocation_Directory('%ls') OK\n", path);
+
+ FARString strNewCurDir;
+ apiGetCurrentDirectory(strNewCurDir);
+
+ if ((PanelMode == NORMAL_PANEL) &&
+ (GetType() == FILE_PANEL) &&
+ !StrCmpI(strCurDir,strNewCurDir) &&
+ IsVisible())
+ {
+ // А нужно ли делать здесь Update????
+ Update(UPDATE_KEEP_SELECTION);
+ }
+ else
+ {
+ int Focus=GetFocus();
+ Panel *NewPanel=CtrlObject->Cp()->ChangePanel(this, FILE_PANEL, TRUE, FALSE);
+ NewPanel->SetCurDir(strNewCurDir,TRUE);
+ NewPanel->Show();
+
+ if (Focus || !CtrlObject->Cp()->GetAnotherPanel(this)->IsVisible())
+ NewPanel->SetFocus();
+
+ if (!Focus && CtrlObject->Cp()->GetAnotherPanel(this)->GetType() == INFO_PANEL)
+ CtrlObject->Cp()->GetAnotherPanel(this)->UpdateKeyBar();
+ }
+
+ return true;
+}
+
+int Panel::OnFCtlSetLocation(const FarPanelLocation *location)
+{
+ if (!location->PluginName)
+ {
+ return SetLocation_Directory(location->Path);
+ }
+
+ auto pPlugin = CtrlObject->Plugins.GetPlugin(location->PluginName);
+ if (!pPlugin)
+ {
+ fprintf(stderr, "OnFCtlSetLocation: wrong plugin='%ls'", location->PluginName);
+ return 0;
+ }
+
+ if (location->HostFile)
+ {
+ return SetLocation_Plugin(true, pPlugin, location->Path, location->HostFile, 0);
+ }
+
+ return SetLocation_Plugin(false, pPlugin, location->Path, nullptr, location->Item);
+}
+
+void Panel::FastFindProcessName(Edit *FindEdit,const wchar_t *Src,FARString &strLastName,FARString &strName)
+{
+ wchar_t *Ptr=(wchar_t *)malloc((StrLength(Src)+StrLength(FindEdit->GetStringAddr())+32)*sizeof(wchar_t));
+
+ if (Ptr)
+ {
+ wcscpy(Ptr,FindEdit->GetStringAddr());
+ wchar_t *EndPtr=Ptr+StrLength(Ptr);
+ wcscat(Ptr,Src);
+ Unquote(EndPtr);
+ EndPtr=Ptr+StrLength(Ptr);
+// DWORD Key;
+
+ for (;;)
+ {
+ if (EndPtr == Ptr)
+ {
+// Key=KEY_NONE;
+ break;
+ }
+
+ if (FindPartName(Ptr,FALSE,1,1))
+ {
+// Key=*(EndPtr-1);
+ *EndPtr=0;
+ FindEdit->SetString(Ptr);
+ strLastName = Ptr;
+ strName = Ptr;
+ FindEdit->Show();
+ break;
+ }
+
+ *--EndPtr=0;
+ }
+
+ free(Ptr);
+ }
+}
+
+int64_t Panel::VMProcess(int OpCode,void *vParam,int64_t iParam)
+{
+ return 0;
+}
+
+// корректировка букв
+static DWORD _CorrectFastFindKbdLayout(INPUT_RECORD *rec,DWORD Key)
+{
+ if ((Key&KEY_ALT))// && Key!=(KEY_ALT|0x3C))
+ {
+ if ((Key& KEY_SHIFT))
+ {
+ switch (Key)
+ // исключения (перекодированные в keyboard.cpp)
+ case KEY_ALT+KEY_SHIFT+'`':
+ case KEY_ALT+KEY_SHIFT+'_':
+ case KEY_ALT+KEY_SHIFT+'=':
+ return Key;
+ }
+ // // _SVS(SysLog(L"_CorrectFastFindKbdLayout>>> %ls | %ls",_FARKEY_ToName(Key),_INPUT_RECORD_Dump(rec)));
+ if (rec->Event.KeyEvent.uChar.UnicodeChar && WCHAR(Key&KEY_MASKF) != rec->Event.KeyEvent.uChar.UnicodeChar) //???
+ Key=(Key&0xFFF10000)|rec->Event.KeyEvent.uChar.UnicodeChar; //???
+
+ // // _SVS(SysLog(L"_CorrectFastFindKbdLayout<<< %ls | %ls",_FARKEY_ToName(Key),_INPUT_RECORD_Dump(rec)));
+ }
+
+ return Key;
+}
+
+void Panel::FastFind(int FirstKey)
+{
+ // // _SVS(CleverSysLog Clev(L"Panel::FastFind"));
+ INPUT_RECORD rec;
+ FARString strLastName, strName;
+ int Key,KeyToProcess=0;
+ WaitInFastFind++;
+ {
+ int FindX=Min(X1+9,ScrX-22);
+ int FindY=Min(Y2,ScrY-2);
+ ChangeMacroMode MacroMode(MACRO_SEARCH);
+ SaveScreen SaveScr(FindX,FindY,FindX+21,FindY+2);
+ FastFindShow(FindX,FindY);
+ Edit FindEdit;
+ FindEdit.SetPosition(FindX+2,FindY+1,FindX+19,FindY+1);
+ FindEdit.SetEditBeyondEnd(FALSE);
+ FindEdit.SetObjectColor(COL_DIALOGEDIT);
+ FindEdit.Show();
+
+ while (!KeyToProcess)
+ {
+ if (FirstKey)
+ {
+ FirstKey=_CorrectFastFindKbdLayout(FrameManager->GetLastInputRecord(),FirstKey);
+ // // _SVS(SysLog(L"Panel::FastFind FirstKey=%ls %ls",_FARKEY_ToName(FirstKey),_INPUT_RECORD_Dump(FrameManager->GetLastInputRecord())));
+ // // _SVS(SysLog(L"if (FirstKey)"));
+ Key=FirstKey;
+ }
+ else
+ {
+ // // _SVS(SysLog(L"else if (FirstKey)"));
+ Key=GetInputRecord(&rec);
+
+ if (rec.EventType==MOUSE_EVENT)
+ {
+ if (!(rec.Event.MouseEvent.dwButtonState & 3))
+ continue;
+ else
+ Key=KEY_ESC;
+ }
+ else if (!rec.EventType || rec.EventType==KEY_EVENT || rec.EventType==FARMACRO_KEY_EVENT)
+ {
+ // для вставки воспользуемся макродвижком...
+ if (Key==KEY_CTRLV || Key==KEY_SHIFTINS || Key==KEY_SHIFTNUMPAD0)
+ {
+ wchar_t *ClipText=PasteFromClipboard();
+
+ if (ClipText)
+ {
+ if (*ClipText)
+ {
+ FastFindProcessName(&FindEdit,ClipText,strLastName,strName);
+ FastFindShow(FindX,FindY);
+ }
+
+ free(ClipText);
+ }
+
+ continue;
+ }
+ else if (Key == KEY_OP_XLAT)
+ {
+ FARString strTempName;
+ FindEdit.Xlat();
+ FindEdit.GetString(strTempName);
+ FindEdit.SetString(L"");
+ FastFindProcessName(&FindEdit,strTempName,strLastName,strName);
+ FastFindShow(FindX,FindY);
+ continue;
+ }
+ else if (Key == KEY_OP_PLAINTEXT)
+ {
+ FARString strTempName;
+ FindEdit.ProcessKey(Key);
+ FindEdit.GetString(strTempName);
+ FindEdit.SetString(L"");
+ FastFindProcessName(&FindEdit,strTempName,strLastName,strName);
+ FastFindShow(FindX,FindY);
+ continue;
+ }
+ else
+ Key=_CorrectFastFindKbdLayout(&rec,Key);
+ }
+ }
+
+ if (Key==KEY_ESC || Key==KEY_F10)
+ {
+ KeyToProcess=KEY_NONE;
+ break;
+ }
+
+ // // _SVS(if (!FirstKey) SysLog(L"Panel::FastFind Key=%ls %ls",_FARKEY_ToName(Key),_INPUT_RECORD_Dump(&rec)));
+ if (Key>=KEY_ALT_BASE+0x01 && Key<=KEY_ALT_BASE+65535)
+ Key=Lower(static_cast<WCHAR>(Key-KEY_ALT_BASE));
+
+ if (Key>=KEY_ALTSHIFT_BASE+0x01 && Key<=KEY_ALTSHIFT_BASE+65535)
+ Key=Lower(static_cast<WCHAR>(Key-KEY_ALTSHIFT_BASE));
+
+ if (Key==KEY_MULTIPLY)
+ Key=L'*';
+
+ switch (Key)
+ {
+ case KEY_F1:
+ {
+ FindEdit.Hide();
+ SaveScr.RestoreArea();
+ {
+ Help Hlp(L"FastFind");
+ }
+ FindEdit.Show();
+ FastFindShow(FindX,FindY);
+ break;
+ }
+ case KEY_CTRLNUMENTER:
+ case KEY_CTRLENTER:
+ FindPartName(strName,TRUE,1,1);
+ FindEdit.Show();
+ FastFindShow(FindX,FindY);
+ break;
+ case KEY_CTRLSHIFTNUMENTER:
+ case KEY_CTRLSHIFTENTER:
+ FindPartName(strName,TRUE,-1,1);
+ FindEdit.Show();
+ FastFindShow(FindX,FindY);
+ break;
+ case KEY_NONE:
+ case KEY_IDLE:
+ break;
+ default:
+
+ if ((Key<32 || Key>=65536) && Key!=KEY_BS && Key!=KEY_CTRLY &&
+ Key!=KEY_CTRLBS && Key!=KEY_ALT && Key!=KEY_SHIFT &&
+ Key!=KEY_CTRL && Key!=KEY_RALT && Key!=KEY_RCTRL &&
+ !(Key==KEY_CTRLINS||Key==KEY_CTRLNUMPAD0) && !(Key==KEY_SHIFTINS||Key==KEY_SHIFTNUMPAD0))
+ {
+ KeyToProcess=Key;
+ break;
+ }
+
+ if (FindEdit.ProcessKey(Key))
+ {
+ FindEdit.GetString(strName);
+
+ // уберем двойные '**'
+ if (strName.GetLength() > 1
+ && strName.At(strName.GetLength()-1) == L'*'
+ && strName.At(strName.GetLength()-2) == L'*')
+ {
+ strName.Truncate(strName.GetLength()-1);
+ FindEdit.SetString(strName);
+ }
+
+ /* $ 09.04.2001 SVS
+ проблемы с быстрым поиском.
+ Подробнее в 00573.ChangeDirCrash.txt
+ */
+ if (strName.At(0) == L'"')
+ {
+ strName.LShift(1);
+ FindEdit.SetString(strName);
+ }
+
+ if (FindPartName(strName,FALSE,1,1))
+ {
+ strLastName = strName;
+ }
+ else
+ {
+ if (CtrlObject->Macro.IsExecuting())// && CtrlObject->Macro.GetLevelState() > 0) // если вставка макросом...
+ {
+ //CtrlObject->Macro.DropProcess(); // ... то дропнем макропроцесс
+ //CtrlObject->Macro.PopState();
+ ;
+ }
+
+ FindEdit.SetString(strLastName);
+ strName = strLastName;
+ }
+
+ FindEdit.Show();
+ FastFindShow(FindX,FindY);
+ }
+
+ break;
+ }
+
+ FirstKey=0;
+ }
+ }
+ WaitInFastFind--;
+ Show();
+ CtrlObject->MainKeyBar->Redraw();
+ ScrBuf.Flush();
+ Panel *ActivePanel=CtrlObject->Cp()->ActivePanel;
+
+ if ((KeyToProcess==KEY_ENTER||KeyToProcess==KEY_NUMENTER) && ActivePanel->GetType()==TREE_PANEL)
+ ((TreeList *)ActivePanel)->ProcessEnter();
+ else
+ CtrlObject->Cp()->ProcessKey(KeyToProcess);
+}
+
+
+void Panel::FastFindShow(int FindX,int FindY)
+{
+ SetColor(COL_DIALOGTEXT);
+ GotoXY(FindX+1,FindY+1);
+ Text(L" ");
+ GotoXY(FindX+20,FindY+1);
+ Text(L" ");
+ Box(FindX,FindY,FindX+21,FindY+2,COL_DIALOGBOX,DOUBLE_BOX);
+ GotoXY(FindX+7,FindY);
+ SetColor(COL_DIALOGBOXTITLE);
+ Text(MSearchFileTitle);
+}
+
+
+void Panel::SetFocus()
+{
+ if (CtrlObject->Cp()->ActivePanel!=this)
+ {
+ CtrlObject->Cp()->ActivePanel->KillFocus();
+ CtrlObject->Cp()->ActivePanel=this;
+ }
+
+ ProcessPluginEvent(FE_GOTFOCUS,nullptr);
+
+ if (!GetFocus())
+ {
+ CtrlObject->Cp()->RedrawKeyBar();
+ Focus=TRUE;
+ Redraw();
+ FarChDir(strCurDir);
+ }
+}
+
+
+void Panel::KillFocus()
+{
+ Focus=FALSE;
+ ProcessPluginEvent(FE_KILLFOCUS,nullptr);
+ Redraw();
+}
+
+
+int Panel::PanelProcessMouse(MOUSE_EVENT_RECORD *MouseEvent,int &RetCode)
+{
+ RetCode=TRUE;
+
+ if (!ModalMode && !MouseEvent->dwMousePosition.Y)
+ {
+ if (MouseEvent->dwMousePosition.X==ScrX)
+ {
+ if (Opt.ScreenSaver && !(MouseEvent->dwButtonState & 3))
+ {
+ EndDrag();
+ ScreenSaver(TRUE);
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ((MouseEvent->dwButtonState & 3) && !MouseEvent->dwEventFlags)
+ {
+ EndDrag();
+
+ if (!MouseEvent->dwMousePosition.X)
+ CtrlObject->Cp()->ProcessKey(KEY_CTRLO);
+ else
+ ShellOptions(0,MouseEvent);
+
+ return TRUE;
+ }
+ }
+ }
+
+ if (!IsVisible() ||
+ (MouseEvent->dwMousePosition.X<X1 || MouseEvent->dwMousePosition.X>X2 ||
+ MouseEvent->dwMousePosition.Y<Y1 || MouseEvent->dwMousePosition.Y>Y2))
+ {
+ RetCode=FALSE;
+ return TRUE;
+ }
+
+ if (DragX!=-1)
+ {
+ if (!(MouseEvent->dwButtonState & 3))
+ {
+ EndDrag();
+
+ if (!MouseEvent->dwEventFlags && SrcDragPanel!=this)
+ {
+ MoveToMouse(MouseEvent);
+ Redraw();
+ SrcDragPanel->ProcessKey(DragMove ? KEY_DRAGMOVE:KEY_DRAGCOPY);
+ }
+
+ return TRUE;
+ }
+
+ if (MouseEvent->dwMousePosition.Y<=Y1 || MouseEvent->dwMousePosition.Y>=Y2 ||
+ !CtrlObject->Cp()->GetAnotherPanel(SrcDragPanel)->IsVisible())
+ {
+ EndDrag();
+ return TRUE;
+ }
+
+ if ((MouseEvent->dwButtonState & 2) && !MouseEvent->dwEventFlags)
+ DragMove=!DragMove;
+
+ if (MouseEvent->dwButtonState & 1)
+ {
+ if ((abs(MouseEvent->dwMousePosition.X-DragX)>15 || SrcDragPanel!=this) &&
+ !ModalMode)
+ {
+ if (SrcDragPanel->GetSelCount()==1 && !DragSaveScr)
+ {
+ SrcDragPanel->GoToFile(strDragName);
+ SrcDragPanel->Show();
+ }
+
+ DragMessage(MouseEvent->dwMousePosition.X,MouseEvent->dwMousePosition.Y,DragMove);
+ return TRUE;
+ }
+ else
+ {
+ delete DragSaveScr;
+ DragSaveScr=nullptr;
+ }
+ }
+ }
+
+ if (!(MouseEvent->dwButtonState & 3))
+ return TRUE;
+
+ if ((MouseEvent->dwButtonState & 1) && !MouseEvent->dwEventFlags &&
+ X2-X1<ScrX)
+ {
+ DWORD FileAttr;
+ MoveToMouse(MouseEvent);
+ GetSelNameCompat(nullptr,FileAttr);
+
+ if (GetSelNameCompat(&strDragName,FileAttr) && !TestParentFolderName(strDragName))
+ {
+ SrcDragPanel=this;
+ DragX=MouseEvent->dwMousePosition.X;
+ DragY=MouseEvent->dwMousePosition.Y;
+ DragMove=ShiftPressed;
+ }
+ }
+
+ return FALSE;
+}
+
+
+int Panel::IsDragging()
+{
+ return DragSaveScr!=nullptr;
+}
+
+
+void Panel::EndDrag()
+{
+ delete DragSaveScr;
+ DragSaveScr=nullptr;
+ DragX=DragY=-1;
+}
+
+
+void Panel::DragMessage(int X,int Y,int Move)
+{
+ FARString strDragMsg, strSelName;
+ int SelCount,MsgX,Length;
+
+ if (!(SelCount=SrcDragPanel->GetSelCount()))
+ return;
+
+ if (SelCount==1)
+ {
+ FARString strCvtName;
+ DWORD FileAttr;
+ SrcDragPanel->GetSelNameCompat(nullptr,FileAttr);
+ SrcDragPanel->GetSelNameCompat(&strSelName,FileAttr);
+ strCvtName = PointToName(strSelName);
+ EscapeSpace(strCvtName);
+ strSelName = strCvtName;
+ }
+ else
+ strSelName.Format(MSG(MDragFiles), SelCount);
+
+ if (Move)
+ strDragMsg.Format(MSG(MDragMove), strSelName.CPtr());
+ else
+ strDragMsg.Format(MSG(MDragCopy), strSelName.CPtr());
+
+ if ((Length=(int)strDragMsg.GetLength())+X>ScrX)
+ {
+ MsgX=ScrX-Length;
+
+ if (MsgX<0)
+ {
+ MsgX=0;
+ TruncStrFromEnd(strDragMsg,ScrX);
+ Length=(int)strDragMsg.GetLength();
+ }
+ }
+ else
+ MsgX=X;
+
+ ChangePriority ChPriority(ChangePriority::NORMAL);
+ delete DragSaveScr;
+ DragSaveScr=new SaveScreen(MsgX,Y,MsgX+Length-1,Y);
+ GotoXY(MsgX,Y);
+ SetColor(COL_PANELDRAGTEXT);
+ Text(strDragMsg);
+}
+
+
+
+int Panel::GetCurDir(FARString &strCurDir)
+{
+ strCurDir = Panel::strCurDir; // TODO: ОПАСНО!!!
+ return (int)strCurDir.GetLength();
+}
+
+int Panel::GetCurDirPluginAware(FARString &strCurDir)
+{
+ if (PanelMode==PLUGIN_PANEL)
+ {
+ HANDLE hPlugin=GetPluginHandle();
+// PluginHandle *ph = (PluginHandle*)hPlugin;
+ OpenPluginInfo Info;
+ CtrlObject->Plugins.GetOpenPluginInfo(hPlugin,&Info);
+
+ strCurDir.Clear();
+
+ if (Info.HostFile && *Info.HostFile)
+ {
+ strCurDir += Info.HostFile;
+ strCurDir += L"/";
+ }
+
+ strCurDir += Info.CurDir;
+ }
+ else
+ {
+ strCurDir = Panel::strCurDir;
+ }
+
+ return (int)strCurDir.GetLength();
+}
+
+
+
+BOOL Panel::SetCurDir(const wchar_t *CurDir,int ClosePlugin)
+{
+ if (StrCmpI(strCurDir,CurDir) || !TestCurrentDirectory(CurDir))
+ {
+ strCurDir = CurDir;
+
+ if (PanelMode!=PLUGIN_PANEL)
+ PrepareDiskPath(strCurDir);
+ }
+
+ return TRUE;
+}
+
+
+void Panel::InitCurDir(const wchar_t *CurDir)
+{
+ if (StrCmpI(strCurDir,CurDir) || !TestCurrentDirectory(CurDir))
+ {
+ strCurDir = CurDir;
+
+ if (PanelMode!=PLUGIN_PANEL)
+ PrepareDiskPath(strCurDir);
+ }
+}
+
+
+/* $ 14.06.2001 KM
+ + Добавлена установка переменных окружения, определяющих
+ текущие директории дисков как для активной, так и для
+ пассивной панели. Это необходимо программам запускаемым
+ из FAR.
+*/
+/* $ 05.10.2001 SVS
+ ! Давайте для начала выставим нужные значения для пассивной панели,
+ а уж потом...
+ А то фигня какая-то получается...
+*/
+/* $ 14.01.2002 IS
+ ! Убрал установку переменных окружения, потому что она производится
+ в FarChDir, которая теперь используется у нас для установления
+ текущего каталога.
+*/
+int Panel::SetCurPath()
+{
+ if (GetMode()==PLUGIN_PANEL)
+ return TRUE;
+
+ Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
+
+ if (AnotherPanel->GetType()!=PLUGIN_PANEL)
+ {
+ if (IsAlpha(AnotherPanel->strCurDir.At(0)) && AnotherPanel->strCurDir.At(1)==L':' &&
+ Upper(AnotherPanel->strCurDir.At(0))!=Upper(strCurDir.At(0)))
+ {
+ // сначала установим переменные окружения для пассивной панели
+ // (без реальной смены пути, чтобы лишний раз пассивный каталог
+ // не перечитывать)
+ FarChDir(AnotherPanel->strCurDir,FALSE);
+ }
+ }
+
+ if (!FarChDir(strCurDir))
+ {
+ while (!FarChDir(strCurDir))
+ {
+ int Result=TestFolder(strCurDir);
+
+ if (Result == TSTFLD_NOTFOUND)
+ {
+ if (CheckShortcutFolder(&strCurDir,FALSE,TRUE) && FarChDir(strCurDir))
+ {
+ SetCurDir(strCurDir,TRUE);
+ return TRUE;
+ }
+ }
+ else
+ break;
+
+ if (FrameManager && FrameManager->ManagerStarted()) // сначала проверим - а запущен ли менеджер
+ {
+ SetCurDir(DefaultPanelInitialDirectory(),TRUE); // если запущен - выставим путь который мы точно знаем что существует
+ ChangeDisk(); // и вызовем меню выбора дисков
+ }
+ else // оппа...
+ {
+ FARString strTemp=strCurDir;
+ CutToFolderNameIfFolder(strCurDir); // подымаемся вверх, для очередной порции ChDir
+
+ if (strTemp.GetLength()==strCurDir.GetLength()) // здесь проблема - видимо диск недоступен
+ {
+ SetCurDir(DefaultPanelInitialDirectory(),TRUE); // тогда просто сваливаем в каталог, откуда стартанул FAR.
+ break;
+ }
+ else
+ {
+ if (FarChDir(strCurDir))
+ {
+ SetCurDir(strCurDir,TRUE);
+ break;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+void Panel::Hide()
+{
+ ScreenObject::Hide();
+ Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
+
+ if (AnotherPanel->IsVisible())
+ {
+ if (AnotherPanel->GetFocus())
+ if ((AnotherPanel->GetType()==FILE_PANEL && AnotherPanel->IsFullScreen()) ||
+ (GetType()==FILE_PANEL && IsFullScreen()))
+ AnotherPanel->Show();
+ }
+}
+
+
+void Panel::Show()
+{
+ if (Locked())
+ return;
+
+ /* $ 03.10.2001 IS перерисуем строчку меню */
+ if (Opt.ShowMenuBar)
+ CtrlObject->TopMenuBar->Show();
+
+ /* $ 09.05.2001 OT */
+// SavePrevScreen();
+ Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
+
+ if (AnotherPanel->IsVisible() && !GetModalMode())
+ {
+ if (SaveScr)
+ {
+ SaveScr->AppendArea(AnotherPanel->SaveScr);
+ }
+
+ if (AnotherPanel->GetFocus())
+ {
+ if (AnotherPanel->IsFullScreen())
+ {
+ SetVisible(TRUE);
+ return;
+ }
+
+ if (GetType()==FILE_PANEL && IsFullScreen())
+ {
+ ScreenObject::Show();
+ AnotherPanel->Show();
+ return;
+ }
+ }
+ }
+
+ ScreenObject::Show();
+ ShowScreensCount();
+}
+
+
+void Panel::DrawSeparator(int Y)
+{
+ if (Y<Y2)
+ {
+ SetColor(COL_PANELBOX);
+ GotoXY(X1,Y);
+ ShowSeparator(X2-X1+1,1);
+ }
+}
+
+
+void Panel::ShowScreensCount()
+{
+ if (Opt.ShowScreensNumber && !X1)
+ {
+ int Viewers = FrameManager->GetFrameCountByType(MODALTYPE_VIEWER);
+ int Editors = FrameManager->GetFrameCountByType(MODALTYPE_EDITOR);
+ int Dialogs = FrameManager->GetFrameCountByType(MODALTYPE_DIALOG);
+ bool HasPluginsTasks = CtrlObject->Plugins.HasBackgroundTasks();
+
+ if (Viewers > 0 || Editors > 0 || Dialogs > 0 || HasPluginsTasks)
+ {
+ FARString strScreensText;
+
+ char Prefix = '[';
+ if (Viewers > 0)
+ {
+ strScreensText.Format(L"%cV%d", Prefix, Viewers);
+ Prefix = ' ';
+ }
+
+ if (Editors > 0)
+ {
+ strScreensText.AppendFormat(L"%cE%d", Prefix, Editors);
+ Prefix = ' ';
+ }
+
+ if (Dialogs > 0)
+ {
+ strScreensText.AppendFormat(L"%cD%d", Prefix, Dialogs);
+ Prefix = ' ';
+ }
+
+ if (HasPluginsTasks)
+ {
+ const auto &Tasks = CtrlObject->Plugins.BackgroundTasks();
+ for (const auto &It : Tasks)
+ {
+ strScreensText.AppendFormat(L"%c%ls%u", Prefix, It.first.c_str(), It.second);
+ Prefix = ' ';
+ }
+ }
+
+ if (Prefix != '[')
+ {
+ strScreensText += L"]";
+ GotoXY(Opt.ShowColumnTitles ? X1:X1+2,Y1);
+ SetColor(COL_PANELSCREENSNUMBER);
+ Text(strScreensText);
+ }
+ }
+ }
+}
+
+
+void Panel::SetTitle()
+{
+ if (GetFocus())
+ {
+ FARString strTitleDir(L"{");
+
+ if (!strCurDir.IsEmpty())
+ {
+ strTitleDir += strCurDir;
+ }
+ else
+ {
+ FARString strCmdText;
+ CtrlObject->CmdLine->GetCurDir(strCmdText);
+ strTitleDir += strCmdText;
+ }
+
+ strTitleDir += L"}";
+
+ ConsoleTitle::SetFarTitle(strTitleDir);
+ }
+}
+
+FARString &Panel::GetTitle(FARString &strTitle,int SubLen,int TruncSize)
+{
+ FARString strTitleDir;
+ bool truncTitle = (SubLen==-1 || TruncSize==0)?false:true;
+
+ if (PanelMode==PLUGIN_PANEL)
+ {
+ OpenPluginInfo Info;
+ GetOpenPluginInfo(&Info);
+ strTitleDir = Info.PanelTitle;
+ RemoveExternalSpaces(strTitleDir);
+ if (truncTitle)
+ TruncStr(strTitleDir,SubLen-TruncSize);
+ }
+ else
+ {
+ strTitleDir = strCurDir;
+
+ if (truncTitle)
+ TruncPathStr(strTitleDir,SubLen-TruncSize);
+ }
+
+ strTitle = L" "+strTitleDir+L" ";
+ return strTitle;
+}
+
+int Panel::SetPluginCommand(int Command,int Param1,LONG_PTR Param2)
+{
+ _ALGO(CleverSysLog clv(L"Panel::SetPluginCommand"));
+ _ALGO(SysLog(L"(Command=%ls, Param1=[%d/0x%08X], Param2=[%d/0x%08X])",_FCTL_ToName(Command),(int)Param1,Param1,(int)Param2,Param2));
+ int Result=FALSE;
+ ProcessingPluginCommand++;
+ FilePanels *FPanels=CtrlObject->Cp();
+ PluginCommand=Command;
+
+ switch (Command)
+ {
+ case FCTL_SETVIEWMODE:
+ Result=FPanels->ChangePanelViewMode(this,Param1,FPanels->IsTopFrame());
+ break;
+
+ case FCTL_SETSORTMODE:
+ {
+ int Mode=Param1;
+
+ if ((Mode>SM_DEFAULT) && (Mode<=SM_CHTIME))
+ {
+ SetSortMode(--Mode); // Уменьшим на 1 из-за SM_DEFAULT
+ Result=TRUE;
+ }
+ break;
+ }
+
+ case FCTL_SETNUMERICSORT:
+ {
+ ChangeNumericSort(Param1);
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_SETCASESENSITIVESORT:
+ {
+ ChangeCaseSensitiveSort(Param1);
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_GETPANELPLUGINHANDLE:
+ {
+ *(HANDLE *)Param2 = (GetPluginHandle() != INVALID_HANDLE_VALUE) ? CtrlObject->Plugins.GetRealPluginHandle(GetPluginHandle()) : INVALID_HANDLE_VALUE;
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_SETPANELLOCATION:
+ {
+ Result = OnFCtlSetLocation((const FarPanelLocation *)Param2);
+ break;
+ }
+
+ case FCTL_SETSORTORDER:
+ {
+ ChangeSortOrder(Param1?-1:1);
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_SETDIRECTORIESFIRST:
+ {
+ ChangeDirectoriesFirst(Param1);
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_CLOSEPLUGIN:
+ strPluginParam = (const wchar_t *)Param2;
+ Result=TRUE;
+ //if(Opt.CPAJHefuayor)
+ // CtrlObject->Plugins.ProcessCommandLine((char *)PluginParam);
+ break;
+
+ case FCTL_GETPANELINFO:
+ {
+ if (!Param2)
+ break;
+
+ PanelInfo *Info=(PanelInfo *)Param2;
+ memset(Info,0,sizeof(*Info));
+ UpdateIfRequired();
+
+ switch (GetType())
+ {
+ case FILE_PANEL:
+ Info->PanelType=PTYPE_FILEPANEL;
+ break;
+ case TREE_PANEL:
+ Info->PanelType=PTYPE_TREEPANEL;
+ break;
+ case QVIEW_PANEL:
+ Info->PanelType=PTYPE_QVIEWPANEL;
+ break;
+ case INFO_PANEL:
+ Info->PanelType=PTYPE_INFOPANEL;
+ break;
+ }
+
+ Info->Plugin=(GetMode()==PLUGIN_PANEL);
+ int X1,Y1,X2,Y2;
+ GetPosition(X1,Y1,X2,Y2);
+ Info->PanelRect.left=X1;
+ Info->PanelRect.top=Y1;
+ Info->PanelRect.right=X2;
+ Info->PanelRect.bottom=Y2;
+ Info->Visible=IsVisible();
+ Info->Focus=GetFocus();
+ Info->ViewMode=GetViewMode();
+ Info->SortMode=SM_UNSORTED-UNSORTED+GetSortMode();
+ {
+ static struct
+ {
+ int *Opt;
+ DWORD Flags;
+ } PFLAGS[]=
+ {
+ {&Opt.ShowHidden,PFLAGS_SHOWHIDDEN},
+ {&Opt.Highlight,PFLAGS_HIGHLIGHT},
+ };
+ DWORD Flags=0;
+
+ for (size_t I=0; I < ARRAYSIZE(PFLAGS); ++I)
+ if (*(PFLAGS[I].Opt) )
+ Flags|=PFLAGS[I].Flags;
+
+ Flags|=GetSortOrder()<0?PFLAGS_REVERSESORTORDER:0;
+ Flags|=GetSortGroups()?PFLAGS_USESORTGROUPS:0;
+ Flags|=GetSelectedFirstMode()?PFLAGS_SELECTEDFIRST:0;
+ Flags|=GetDirectoriesFirst()?PFLAGS_DIRECTORIESFIRST:0;
+ Flags|=GetNumericSort()?PFLAGS_NUMERICSORT:0;
+ Flags|=GetCaseSensitiveSort()?PFLAGS_CASESENSITIVESORT:0;
+
+ if (CtrlObject->Cp()->LeftPanel == this)
+ Flags|=PFLAGS_PANELLEFT;
+
+ Info->Flags=Flags;
+ }
+
+ if (GetType()==FILE_PANEL)
+ {
+ FileList *DestFilePanel=(FileList *)this;
+ static int Reenter=0;
+
+ if (!Reenter && Info->Plugin)
+ {
+ Reenter++;
+ OpenPluginInfo PInfo;
+ DestFilePanel->GetOpenPluginInfo(&PInfo);
+
+ if (PInfo.Flags & OPIF_REALNAMES)
+ Info->Flags |= PFLAGS_REALNAMES;
+
+ if (!(PInfo.Flags & OPIF_USEHIGHLIGHTING))
+ Info->Flags &= ~PFLAGS_HIGHLIGHT;
+
+ if (PInfo.Flags & OPIF_USECRC32)
+ Info->Flags |= PFLAGS_USECRC32;
+
+ Reenter--;
+ }
+
+ DestFilePanel->PluginGetPanelInfo(*Info);
+ }
+
+ if (!Info->Plugin) // $ 12.12.2001 DJ - на неплагиновой панели - всегда реальные имена
+ Info->Flags |= PFLAGS_REALNAMES;
+
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_GETPANELHOSTFILE:
+ case FCTL_GETPANELFORMAT:
+ case FCTL_GETPANELDIR:
+ {
+ FARString strTemp;
+
+ if (Command == FCTL_GETPANELDIR)
+ GetCurDir(strTemp);
+
+ if (GetType()==FILE_PANEL)
+ {
+ FileList *DestFilePanel=(FileList *)this;
+ static int Reenter=0;
+
+ if (!Reenter && GetMode()==PLUGIN_PANEL)
+ {
+ Reenter++;
+
+ OpenPluginInfo PInfo;
+ DestFilePanel->GetOpenPluginInfo(&PInfo);
+
+ switch (Command)
+ {
+ case FCTL_GETPANELHOSTFILE:
+ strTemp=PInfo.HostFile;
+ break;
+ case FCTL_GETPANELFORMAT:
+ strTemp=PInfo.Format;
+ break;
+ case FCTL_GETPANELDIR:
+ strTemp=PInfo.CurDir;
+ break;
+ }
+
+ Reenter--;
+ }
+ }
+
+ if (Param1&&Param2)
+ far_wcsncpy((wchar_t*)Param2,strTemp,Param1);
+
+ Result=(int)strTemp.GetLength()+1;
+ break;
+ }
+
+ case FCTL_GETCOLUMNTYPES:
+ case FCTL_GETCOLUMNWIDTHS:
+
+ if (GetType()==FILE_PANEL)
+ {
+ FARString strColumnTypes,strColumnWidths;
+ ((FileList *)this)->PluginGetColumnTypesAndWidths(strColumnTypes,strColumnWidths);
+
+ if (Command==FCTL_GETCOLUMNTYPES)
+ {
+ if (Param1&&Param2)
+ far_wcsncpy((wchar_t*)Param2,strColumnTypes,Param1);
+
+ Result=(int)strColumnTypes.GetLength()+1;
+ }
+ else
+ {
+ if (Param1&&Param2)
+ far_wcsncpy((wchar_t*)Param2,strColumnWidths,Param1);
+
+ Result=(int)strColumnWidths.GetLength()+1;
+ }
+ }
+ break;
+
+ case FCTL_GETPANELITEM:
+ {
+ Result=(int)((FileList*)this)->PluginGetPanelItem(Param1,(PluginPanelItem*)Param2);
+ break;
+ }
+
+ case FCTL_GETSELECTEDPANELITEM:
+ {
+ Result=(int)((FileList*)this)->PluginGetSelectedPanelItem(Param1,(PluginPanelItem*)Param2);
+ break;
+ }
+
+ case FCTL_GETCURRENTPANELITEM:
+ {
+ PanelInfo Info;
+ FileList *DestPanel = ((FileList*)this);
+ DestPanel->PluginGetPanelInfo(Info);
+ Result = (int)DestPanel->PluginGetPanelItem(Info.CurrentItem,(PluginPanelItem*)Param2);
+ break;
+ }
+
+ case FCTL_BEGINSELECTION:
+ {
+ if (GetType()==FILE_PANEL)
+ {
+ ((FileList *)this)->PluginBeginSelection();
+ Result=TRUE;
+ }
+ break;
+ }
+
+ case FCTL_SETSELECTION:
+ {
+ if (GetType()==FILE_PANEL)
+ {
+ ((FileList *)this)->PluginSetSelection(Param1,Param2?true:false);
+ Result=TRUE;
+ }
+ break;
+ }
+
+ case FCTL_CLEARSELECTION:
+ {
+ if (GetType()==FILE_PANEL)
+ {
+ reinterpret_cast<FileList*>(this)->PluginClearSelection(Param1);
+ Result=TRUE;
+ }
+ break;
+ }
+
+ case FCTL_ENDSELECTION:
+ {
+ if (GetType()==FILE_PANEL)
+ {
+ ((FileList *)this)->PluginEndSelection();
+ Result=TRUE;
+ }
+ break;
+ }
+
+ case FCTL_UPDATEPANEL:
+ Update(Param1?UPDATE_KEEP_SELECTION:0);
+
+ if (GetType() == QVIEW_PANEL)
+ UpdateViewPanel();
+
+ Result=TRUE;
+ break;
+
+ case FCTL_REDRAWPANEL:
+ {
+ PanelRedrawInfo *Info=(PanelRedrawInfo *)Param2;
+
+ if (Info)
+ {
+ CurFile=Info->CurrentItem;
+ CurTopFile=Info->TopPanelItem;
+ }
+
+ // $ 12.05.2001 DJ перерисовываемся только в том случае, если мы - текущий фрейм
+ if (FPanels->IsTopFrame())
+ Redraw();
+
+ Result=TRUE;
+ break;
+ }
+
+ case FCTL_SETPANELDIR:
+ {
+ if (Param2)
+ {
+ Result = SetCurDir((const wchar_t *)Param2,TRUE);
+ // restore current directory to active panel path
+ Panel* ActivePanel = CtrlObject->Cp()->ActivePanel;
+ if (Result && this != ActivePanel)
+ {
+ ActivePanel->SetCurPath();
+ }
+ }
+ break;
+ }
+
+ }
+
+ ProcessingPluginCommand--;
+ return Result;
+}
+
+
+int Panel::GetCurName(FARString &strName)
+{
+ strName.Clear();
+ return FALSE;
+}
+
+
+int Panel::GetCurBaseName(FARString &strName)
+{
+ strName.Clear();
+ return FALSE;
+}
+
+BOOL Panel::NeedUpdatePanel(Panel *AnotherPanel)
+{
+ /* Обновить, если обновление разрешено и пути совпадают */
+ if ((!Opt.AutoUpdateLimit || static_cast<DWORD>(GetFileCount()) <= Opt.AutoUpdateLimit) &&
+ !StrCmpI(AnotherPanel->strCurDir,strCurDir))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+bool Panel::SaveShortcutFolder(int Pos)
+{
+ FARString strShortcutFolder,strPluginModule,strPluginFile,strPluginData;
+
+ if (PanelMode==PLUGIN_PANEL)
+ {
+ HANDLE hPlugin=GetPluginHandle();
+ PluginHandle *ph = (PluginHandle*)hPlugin;
+ strPluginModule = ph->pPlugin->GetModuleName();
+ OpenPluginInfo Info;
+ CtrlObject->Plugins.GetOpenPluginInfo(hPlugin,&Info);
+ strPluginFile = Info.HostFile;
+ strShortcutFolder = Info.CurDir;
+ strPluginData = Info.ShortcutData;
+ }
+ else
+ {
+ strPluginModule.Clear();
+ strPluginFile.Clear();
+ strPluginData.Clear();
+ strShortcutFolder = strCurDir;
+ }
+
+ if (Bookmarks().Set(Pos, &strShortcutFolder, &strPluginModule, &strPluginFile, &strPluginData))
+ return true;
+
+ return true;
+}
+
+/*
+int Panel::ProcessShortcutFolder(int Key,BOOL ProcTreePanel)
+{
+ FARString strShortcutFolder, strPluginModule, strPluginFile, strPluginData;
+
+ if (GetShortcutFolder(Key-KEY_RCTRL0,&strShortcutFolder,&strPluginModule,&strPluginFile,&strPluginData))
+ {
+ Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
+
+ if (ProcTreePanel)
+ {
+ if (AnotherPanel->GetType()==FILE_PANEL)
+ {
+ AnotherPanel->SetCurDir(strShortcutFolder,TRUE);
+ AnotherPanel->Redraw();
+ }
+ else
+ {
+ SetCurDir(strShortcutFolder,TRUE);
+ ProcessKey(KEY_ENTER);
+ }
+ }
+ else
+ {
+ if (AnotherPanel->GetType()==FILE_PANEL && !strPluginModule.IsEmpty())
+ {
+ AnotherPanel->SetCurDir(strShortcutFolder,TRUE);
+ AnotherPanel->Redraw();
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+*/
+
+bool Panel::ExecShortcutFolder(int Pos)
+{
+ FARString strShortcutFolder,strPluginModule,strPluginFile,strPluginData;
+
+ if (Bookmarks().Get(Pos,&strShortcutFolder,&strPluginModule,&strPluginFile,&strPluginData))
+ {
+ Panel *SrcPanel=this;
+ Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
+
+ switch (GetType())
+ {
+ case TREE_PANEL:
+ if (AnotherPanel->GetType()==FILE_PANEL)
+ SrcPanel=AnotherPanel;
+ break;
+
+ case QVIEW_PANEL:
+ case INFO_PANEL:
+ {
+ if (AnotherPanel->GetType()==FILE_PANEL)
+ SrcPanel=AnotherPanel;
+ break;
+ }
+ }
+
+ int CheckFullScreen=SrcPanel->IsFullScreen();
+
+ if (!strPluginModule.IsEmpty())
+ {
+ if (!strPluginFile.IsEmpty())
+ {
+ switch (CheckShortcutFolder(&strPluginFile,TRUE))
+ {
+ case 0:
+ // return FALSE;
+ case -1:
+ return true;
+ }
+
+ /* Своеобразное решение BugZ#50 */
+ FARString strRealDir;
+ strRealDir = strPluginFile;
+
+ if (CutToSlash(strRealDir))
+ {
+ SrcPanel->SetCurDir(strRealDir,TRUE);
+ SrcPanel->GoToFile(PointToName(strPluginFile));
+
+ SrcPanel->ClearAllItem();
+ }
+
+ if (SrcPanel->GetType() == FILE_PANEL)
+ ((FileList*)SrcPanel)->OpenFilePlugin(strPluginFile,FALSE, OFP_SHORTCUT); //???
+
+ if (!strShortcutFolder.IsEmpty())
+ SrcPanel->SetCurDir(strShortcutFolder,FALSE);
+
+ SrcPanel->Show();
+ }
+ else
+ {
+ switch (CheckShortcutFolder(nullptr,TRUE))
+ {
+ case 0:
+ // return FALSE;
+ case -1:
+ return true;
+ }
+
+ for (int I=0; I<CtrlObject->Plugins.GetPluginsCount(); I++)
+ {
+ Plugin *pPlugin = CtrlObject->Plugins.GetPlugin(I);
+
+ if (!StrCmpI(pPlugin->GetModuleName(),strPluginModule))
+ {
+ if (pPlugin->HasOpenPlugin())
+ {
+ HANDLE hNewPlugin=CtrlObject->Plugins.OpenPlugin(pPlugin,OPEN_SHORTCUT,(INT_PTR)strPluginData.CPtr());
+
+ if (hNewPlugin!=INVALID_HANDLE_VALUE)
+ {
+ int CurFocus=SrcPanel->GetFocus();
+
+ Panel *NewPanel=CtrlObject->Cp()->ChangePanel(SrcPanel,FILE_PANEL,TRUE,TRUE);
+ NewPanel->SetPluginMode(hNewPlugin,L"",CurFocus || !CtrlObject->Cp()->GetAnotherPanel(NewPanel)->IsVisible());
+
+ if (!strShortcutFolder.IsEmpty())
+ CtrlObject->Plugins.SetDirectory(hNewPlugin,strShortcutFolder,0);
+
+ NewPanel->Update(0);
+ NewPanel->Show();
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ switch (CheckShortcutFolder(&strShortcutFolder,FALSE))
+ {
+ case 0:
+ // return FALSE;
+ case -1:
+ return true;
+ }
+
+ /*
+ if (SrcPanel->GetType()!=FILE_PANEL)
+ {
+ SrcPanel=CtrlObject->Cp()->ChangePanel(SrcPanel,FILE_PANEL,TRUE,TRUE);
+ }
+ */
+
+ SrcPanel->SetCurDir(strShortcutFolder,TRUE);
+
+ if (CheckFullScreen!=SrcPanel->IsFullScreen())
+ CtrlObject->Cp()->GetAnotherPanel(SrcPanel)->Show();
+
+ SrcPanel->Redraw();
+ return true;
+ }
+ return false;
+}
+