Merge pull request #2212 from unxed/ctrl_yo
[far2l.git] / far2l / src / filepanels.cpp
blobe5f9e21b3c94129396d90fa59e142bdc9ae21018
1 /*
2 filepanels.cpp
4 Файловые панели
5 */
6 /*
7 Copyright (c) 1996 Eugene Roshal
8 Copyright (c) 2000 Far Group
9 All rights reserved.
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions
13 are met:
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19 3. The name of the authors may not be used to endorse or promote products
20 derived from this software without specific prior written permission.
22 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "headers.hpp"
36 #include "filepanels.hpp"
37 #include "keys.hpp"
38 #include "macroopcode.hpp"
39 #include "lang.hpp"
40 #include "ctrlobj.hpp"
41 #include "filelist.hpp"
42 #include "rdrwdsk.hpp"
43 #include "cmdline.hpp"
44 #include "treelist.hpp"
45 #include "qview.hpp"
46 #include "infolist.hpp"
47 #include "help.hpp"
48 #include "filefilter.hpp"
49 #include "findfile.hpp"
50 #include "savescr.hpp"
51 #include "manager.hpp"
52 #include "syslog.hpp"
53 #include "options.hpp"
54 #include "pathmix.hpp"
55 #include "dirmix.hpp"
56 #include "interf.hpp"
58 FilePanels::FilePanels()
60 LastLeftFilePanel(nullptr),
61 LastRightFilePanel(nullptr),
62 LeftPanel(CreatePanel(Opt.LeftPanel.Type)),
63 RightPanel(CreatePanel(Opt.RightPanel.Type)),
64 ActivePanel(nullptr),
65 LastLeftType(0),
66 LastRightType(0),
67 LeftStateBeforeHide(0),
68 RightStateBeforeHide(0)
70 _OT(SysLog(L"[%p] FilePanels::FilePanels()", this));
71 MacroMode = MACRO_SHELL;
72 KeyBarVisible = Opt.ShowKeyBar;
73 // SetKeyBar(&MainKeyBar);
74 //_D(SysLog(L"MainKeyBar=0x%p",&MainKeyBar));
77 static void PrepareOptFolder(FARString &strSrc, int IsLocalPath_FarPath)
79 if (strSrc.IsEmpty()) {
80 strSrc = DefaultPanelInitialDirectory();
81 } else {
82 apiExpandEnvironmentStrings(strSrc, strSrc);
85 if (strSrc != L"/") {
86 CheckShortcutFolder(&strSrc, FALSE, TRUE);
89 // ConvertNameToFull(strSrc,strSrc);
92 void FilePanels::Init()
94 SetPanelPositions(FileList::IsModeFullScreen(Opt.LeftPanel.ViewMode),
95 FileList::IsModeFullScreen(Opt.RightPanel.ViewMode));
96 LeftPanel->SetViewMode(Opt.LeftPanel.ViewMode);
97 RightPanel->SetViewMode(Opt.RightPanel.ViewMode);
98 LeftPanel->SetSortMode(std::min(std::max(Opt.LeftPanel.SortMode, 0), (int)MAX_PANEL_SORT_MODE));
99 RightPanel->SetSortMode(std::min(std::max(Opt.RightPanel.SortMode, 0), (int)MAX_PANEL_SORT_MODE));
100 LeftPanel->SetNumericSort(Opt.LeftPanel.NumericSort);
101 RightPanel->SetNumericSort(Opt.RightPanel.NumericSort);
102 LeftPanel->SetCaseSensitiveSort(Opt.LeftPanel.CaseSensitiveSort);
103 RightPanel->SetCaseSensitiveSort(Opt.RightPanel.CaseSensitiveSort);
104 LeftPanel->SetSortOrder(Opt.LeftPanel.SortOrder);
105 RightPanel->SetSortOrder(Opt.RightPanel.SortOrder);
106 LeftPanel->SetSortGroups(Opt.LeftPanel.SortGroups);
107 RightPanel->SetSortGroups(Opt.RightPanel.SortGroups);
108 LeftPanel->SetSelectedFirstMode(Opt.LeftSelectedFirst);
109 RightPanel->SetSelectedFirstMode(Opt.RightSelectedFirst);
110 LeftPanel->SetDirectoriesFirst(Opt.LeftPanel.DirectoriesFirst);
111 RightPanel->SetDirectoriesFirst(Opt.RightPanel.DirectoriesFirst);
112 SetCanLoseFocus(TRUE);
113 Panel *PassivePanel = nullptr;
114 int PassiveIsLeftFlag = TRUE;
116 if (Opt.LeftPanel.Focus) {
117 ActivePanel = LeftPanel;
118 PassivePanel = RightPanel;
119 PassiveIsLeftFlag = FALSE;
120 } else {
121 ActivePanel = RightPanel;
122 PassivePanel = LeftPanel;
123 PassiveIsLeftFlag = TRUE;
126 ActivePanel->SetFocus();
127 // пытаемся избавится от зависания при запуске
128 int IsLocalPath_FarPath = IsLocalPath(g_strFarPath);
129 PrepareOptFolder(Opt.strLeftFolder, IsLocalPath_FarPath);
130 PrepareOptFolder(Opt.strRightFolder, IsLocalPath_FarPath);
132 if (Opt.AutoSaveSetup || !Opt.SetupArgv) {
133 if (apiGetFileAttributes(Opt.strLeftFolder) != INVALID_FILE_ATTRIBUTES)
134 LeftPanel->InitCurDir(Opt.strLeftFolder);
136 if (apiGetFileAttributes(Opt.strRightFolder) != INVALID_FILE_ATTRIBUTES)
137 RightPanel->InitCurDir(Opt.strRightFolder);
140 if (!Opt.AutoSaveSetup) {
141 if (Opt.SetupArgv >= 1) {
142 if (ActivePanel == RightPanel) {
143 if (apiGetFileAttributes(Opt.strRightFolder) != INVALID_FILE_ATTRIBUTES)
144 RightPanel->InitCurDir(Opt.strRightFolder);
145 } else {
146 if (apiGetFileAttributes(Opt.strLeftFolder) != INVALID_FILE_ATTRIBUTES)
147 LeftPanel->InitCurDir(Opt.strLeftFolder);
150 if (Opt.SetupArgv == 2) {
151 if (ActivePanel == LeftPanel) {
152 if (apiGetFileAttributes(Opt.strRightFolder) != INVALID_FILE_ATTRIBUTES)
153 RightPanel->InitCurDir(Opt.strRightFolder);
154 } else {
155 if (apiGetFileAttributes(Opt.strLeftFolder) != INVALID_FILE_ATTRIBUTES)
156 LeftPanel->InitCurDir(Opt.strLeftFolder);
161 const wchar_t *PassiveFolder = PassiveIsLeftFlag ? Opt.strLeftFolder : Opt.strRightFolder;
163 if (Opt.SetupArgv < 2 && *PassiveFolder
164 && (apiGetFileAttributes(PassiveFolder) != INVALID_FILE_ATTRIBUTES)) {
165 PassivePanel->InitCurDir(PassiveFolder);
169 #if 1
171 //! Вначале "показываем" пассивную панель
172 if (PassiveIsLeftFlag) {
173 if (Opt.LeftPanel.Visible) {
174 LeftPanel->Show();
177 if (Opt.RightPanel.Visible) {
178 RightPanel->Show();
180 } else {
181 if (Opt.RightPanel.Visible) {
182 RightPanel->Show();
185 if (Opt.LeftPanel.Visible) {
186 LeftPanel->Show();
190 #endif
192 // при понашенных панелях не забыть бы выставить корректно каталог в CmdLine
193 if (!Opt.RightPanel.Visible && !Opt.LeftPanel.Visible) {
194 CtrlObject->CmdLine->SetCurDir(PassiveIsLeftFlag ? Opt.strRightFolder : Opt.strLeftFolder);
197 SetKeyBar(&MainKeyBar);
198 MainKeyBar.SetOwner(this);
201 FilePanels::~FilePanels()
203 _OT(SysLog(L"[%p] FilePanels::~FilePanels()", this));
205 if (LastLeftFilePanel != LeftPanel && LastLeftFilePanel != RightPanel)
206 DeletePanel(LastLeftFilePanel);
208 if (LastRightFilePanel != LeftPanel && LastRightFilePanel != RightPanel)
209 DeletePanel(LastRightFilePanel);
211 DeletePanel(LeftPanel);
212 LeftPanel = nullptr;
213 DeletePanel(RightPanel);
214 RightPanel = nullptr;
217 void FilePanels::SetPanelPositions(int LeftFullScreen, int RightFullScreen)
219 if (Opt.WidthDecrement < -(ScrX / 2 - 10))
220 Opt.WidthDecrement = -(ScrX / 2 - 10);
222 if (Opt.WidthDecrement > (ScrX / 2 - 10))
223 Opt.WidthDecrement = (ScrX / 2 - 10);
225 Opt.LeftHeightDecrement = Max(0, Min(Opt.LeftHeightDecrement, ScrY - 7));
226 Opt.RightHeightDecrement = Max(0, Min(Opt.RightHeightDecrement, ScrY - 7));
228 if (LeftFullScreen) {
229 LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX,
230 ScrY - 1 - (Opt.ShowKeyBar) - Opt.LeftHeightDecrement);
231 LeftPanel->ViewSettings.FullScreen = 1;
232 } else {
233 LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX / 2 - Opt.WidthDecrement,
234 ScrY - 1 - (Opt.ShowKeyBar) - Opt.LeftHeightDecrement);
237 if (RightFullScreen) {
238 RightPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX,
239 ScrY - 1 - (Opt.ShowKeyBar) - Opt.RightHeightDecrement);
240 RightPanel->ViewSettings.FullScreen = 1;
241 } else {
242 RightPanel->SetPosition(ScrX / 2 + 1 - Opt.WidthDecrement, Opt.ShowMenuBar ? 1 : 0, ScrX,
243 ScrY - 1 - (Opt.ShowKeyBar) - Opt.RightHeightDecrement);
247 void FilePanels::SetScreenPosition()
249 _OT(SysLog(L"[%p] FilePanels::SetScreenPosition() {%d, %d - %d, %d}", this, X1, Y1, X2, Y2));
250 CtrlObject->CmdLine->SetPosition(0, ScrY - (Opt.ShowKeyBar), ScrX - 1, ScrY - (Opt.ShowKeyBar));
251 TopMenuBar.SetPosition(0, 0, ScrX, 0);
252 MainKeyBar.SetPosition(0, ScrY, ScrX, ScrY);
253 SetPanelPositions(LeftPanel->IsFullScreen(), RightPanel->IsFullScreen());
254 SetPosition(0, 0, ScrX, ScrY);
257 void FilePanels::RedrawKeyBar()
259 ActivePanel->UpdateKeyBar();
260 MainKeyBar.Redraw();
263 Panel *FilePanels::CreatePanel(int Type)
265 Panel *pResult = nullptr;
267 switch (Type) {
268 case FILE_PANEL:
269 pResult = new FileList;
270 break;
271 case TREE_PANEL:
272 pResult = new TreeList;
273 break;
274 case QVIEW_PANEL:
275 pResult = new QuickView;
276 break;
277 case INFO_PANEL:
278 pResult = new InfoList;
279 break;
282 if (pResult)
283 pResult->SetOwner(this);
285 return pResult;
288 void FilePanels::DeletePanel(Panel *Deleted)
290 if (!Deleted)
291 return;
293 if (Deleted == LastLeftFilePanel)
294 LastLeftFilePanel = nullptr;
296 if (Deleted == LastRightFilePanel)
297 LastRightFilePanel = nullptr;
299 delete Deleted;
302 int FilePanels::SetAnotherPanelFocus()
304 int Ret = FALSE;
306 if (ActivePanel == LeftPanel) {
307 if (RightPanel->IsVisible()) {
308 RightPanel->SetFocus();
309 Ret = TRUE;
311 } else {
312 if (LeftPanel->IsVisible()) {
313 LeftPanel->SetFocus();
314 Ret = TRUE;
318 return Ret;
321 int FilePanels::SwapPanels()
323 int Ret = FALSE; // это значит ни одна из панелей не видна
325 if (LeftPanel->IsVisible() || RightPanel->IsVisible()) {
326 int XL1, YL1, XL2, YL2;
327 int XR1, YR1, XR2, YR2;
328 LeftPanel->GetPosition(XL1, YL1, XL2, YL2);
329 RightPanel->GetPosition(XR1, YR1, XR2, YR2);
331 if (!LeftPanel->ViewSettings.FullScreen || !RightPanel->ViewSettings.FullScreen) {
332 Opt.WidthDecrement = -Opt.WidthDecrement;
334 Opt.LeftHeightDecrement^= Opt.RightHeightDecrement;
335 Opt.RightHeightDecrement = Opt.LeftHeightDecrement ^ Opt.RightHeightDecrement;
336 Opt.LeftHeightDecrement^= Opt.RightHeightDecrement;
339 Panel *Swap;
340 int SwapType;
341 Swap = LeftPanel;
342 LeftPanel = RightPanel;
343 RightPanel = Swap;
344 Swap = LastLeftFilePanel;
345 LastLeftFilePanel = LastRightFilePanel;
346 LastRightFilePanel = Swap;
347 SwapType = LastLeftType;
348 LastLeftType = LastRightType;
349 LastRightType = SwapType;
350 FileFilter::SwapFilter();
351 Ret = TRUE;
353 SetScreenPosition();
354 FrameManager->RefreshFrame();
355 return Ret;
358 int64_t FilePanels::VMProcess(MacroOpcode OpCode, void *vParam, int64_t iParam)
360 return ActivePanel->VMProcess(OpCode, vParam, iParam);
363 int FilePanels::ProcessKey(FarKey Key)
365 if (!Key)
366 return TRUE;
368 if ((Key == KEY_CTRLLEFT || Key == KEY_CTRLRIGHT || Key == KEY_CTRLNUMPAD4 || Key == KEY_CTRLNUMPAD6
369 /* || Key==KEY_CTRLUP || Key==KEY_CTRLDOWN || Key==KEY_CTRLNUMPAD8 || Key==KEY_CTRLNUMPAD2 */)
370 && (CtrlObject->CmdLine->GetLength() > 0
371 || (!LeftPanel->IsVisible() && !RightPanel->IsVisible()))) {
372 CtrlObject->CmdLine->ProcessKey(Key);
373 return TRUE;
375 SudoClientRegion scr;
376 switch (Key) {
377 case KEY_F1: {
378 if (!LeftPanel->IsVisible() && !RightPanel->IsVisible()) {
379 Help::Present(L"Terminal");
380 } else if (!ActivePanel->ProcessKey(KEY_F1)) {
381 Help::Present(L"Contents");
384 return TRUE;
386 case KEY_TAB: {
387 if (!SetAnotherPanelFocus()) {
388 CtrlObject->CmdLine->ProcessKey(Key);
390 break;
392 case KEY_CTRLF1: {
393 if (LeftPanel->IsVisible()) {
394 LeftPanel->Hide();
396 if (RightPanel->IsVisible())
397 RightPanel->SetFocus();
398 } else {
399 if (!RightPanel->IsVisible())
400 LeftPanel->SetFocus();
402 LeftPanel->Show();
405 Redraw();
406 break;
408 case KEY_CTRLF2: {
409 if (RightPanel->IsVisible()) {
410 RightPanel->Hide();
412 if (LeftPanel->IsVisible())
413 LeftPanel->SetFocus();
414 } else {
415 if (!LeftPanel->IsVisible())
416 RightPanel->SetFocus();
418 RightPanel->Show();
421 Redraw();
422 break;
424 case KEY_CTRLB: {
425 Opt.ShowKeyBar = !Opt.ShowKeyBar;
426 KeyBarVisible = Opt.ShowKeyBar;
428 if (!KeyBarVisible)
429 MainKeyBar.Hide();
431 SetScreenPosition();
432 FrameManager->RefreshFrame();
433 break;
435 case KEY_CTRLL:
436 case KEY_CTRLQ:
437 case KEY_CTRLT: {
438 if (ActivePanel->IsVisible()) {
439 Panel *AnotherPanel = GetAnotherPanel(ActivePanel);
440 int NewType;
442 if (Key == KEY_CTRLL)
443 NewType = INFO_PANEL;
444 else if (Key == KEY_CTRLQ)
445 NewType = QVIEW_PANEL;
446 else
447 NewType = TREE_PANEL;
449 if (ActivePanel->GetType() == NewType)
450 AnotherPanel = ActivePanel;
452 if (!AnotherPanel->ProcessPluginEvent(FE_CLOSE, nullptr)) {
453 if (AnotherPanel->GetType() == NewType)
455 $ 19.09.2000 IS
456 Повторное нажатие на ctrl-l|q|t всегда включает файловую панель
458 AnotherPanel = ChangePanel(AnotherPanel, FILE_PANEL, FALSE, FALSE);
459 else
460 AnotherPanel = ChangePanel(AnotherPanel, NewType, FALSE, FALSE);
463 $ 07.09.2001 VVM
464 ! При возврате из CTRL+Q, CTRL+L восстановим каталог, если активная панель - дерево.
466 if (ActivePanel->GetType() == TREE_PANEL) {
467 FARString strCurDir;
468 ActivePanel->GetCurDir(strCurDir);
469 AnotherPanel->SetCurDir(strCurDir, TRUE);
470 AnotherPanel->Update(0);
471 } else
472 AnotherPanel->Update(UPDATE_KEEP_SELECTION);
474 AnotherPanel->Show();
477 ActivePanel->SetFocus();
480 break;
482 case KEY_CTRLO: {
484 int LeftVisible = LeftPanel->IsVisible();
485 int RightVisible = RightPanel->IsVisible();
486 int HideState = !LeftVisible && !RightVisible;
488 if (!HideState) {
489 LeftStateBeforeHide = LeftVisible;
490 RightStateBeforeHide = RightVisible;
491 LeftPanel->Hide();
492 RightPanel->Hide();
493 FrameManager->RefreshFrame();
494 } else {
495 if (!LeftStateBeforeHide && !RightStateBeforeHide)
496 LeftStateBeforeHide = RightStateBeforeHide = TRUE;
498 if (LeftStateBeforeHide)
499 LeftPanel->Show();
501 if (RightStateBeforeHide)
502 RightPanel->Show();
504 if (!ActivePanel->IsVisible()) {
505 if (ActivePanel == RightPanel)
506 LeftPanel->SetFocus();
507 else
508 RightPanel->SetFocus();
512 break;
514 case KEY_CTRLP: {
515 if (ActivePanel->IsVisible()) {
516 Panel *AnotherPanel = GetAnotherPanel(ActivePanel);
518 if (AnotherPanel->IsVisible())
519 AnotherPanel->Hide();
520 else
521 AnotherPanel->Show();
523 CtrlObject->CmdLine->Redraw();
526 FrameManager->RefreshFrame();
527 break;
529 case KEY_CTRLI: {
530 ActivePanel->EditFilter();
531 return TRUE;
533 case KEY_CTRLU: {
534 if (!LeftPanel->IsVisible() && !RightPanel->IsVisible())
535 CtrlObject->CmdLine->ProcessKey(Key);
536 else
537 SwapPanels();
539 break;
542 $ 08.04.2002 IS
543 При смене диска установим принудительно текущий каталог на активной
544 панели, т.к. система не знает ничего о том, что у Фара две панели, и
545 текущим для системы после смены диска может быть каталог и на пассивной
546 панели
548 case KEY_ALTF1: {
549 LeftPanel->ChangeDisk();
551 if (ActivePanel != LeftPanel)
552 ActivePanel->SetCurPath();
554 break;
556 case KEY_ALTF2: {
557 RightPanel->ChangeDisk();
559 if (ActivePanel != RightPanel)
560 ActivePanel->SetCurPath();
562 break;
564 case KEY_ALTF7: {
565 FindFiles::Present();
566 break;
568 case KEY_CTRLUP:
569 case KEY_CTRLNUMPAD8: {
570 bool Set = false;
571 if (Opt.LeftHeightDecrement < ScrY - 7) {
572 Opt.LeftHeightDecrement++;
573 Set = true;
575 if (Opt.RightHeightDecrement < ScrY - 7) {
576 Opt.RightHeightDecrement++;
577 Set = true;
579 if (Set) {
580 SetScreenPosition();
581 FrameManager->RefreshFrame();
584 break;
586 case KEY_CTRLDOWN:
587 case KEY_CTRLNUMPAD2: {
588 bool Set = false;
589 if (Opt.LeftHeightDecrement > 0) {
590 Opt.LeftHeightDecrement--;
591 Set = true;
593 if (Opt.RightHeightDecrement > 0) {
594 Opt.RightHeightDecrement--;
595 Set = true;
597 if (Set) {
598 SetScreenPosition();
599 FrameManager->RefreshFrame();
602 break;
605 case KEY_CTRLSHIFTUP:
606 case KEY_CTRLSHIFTNUMPAD8: {
607 int &HeightDecrement =
608 (ActivePanel == LeftPanel) ? Opt.LeftHeightDecrement : Opt.RightHeightDecrement;
609 if (HeightDecrement < ScrY - 7) {
610 HeightDecrement++;
611 SetScreenPosition();
612 FrameManager->RefreshFrame();
614 break;
617 case KEY_CTRLSHIFTDOWN:
618 case KEY_CTRLSHIFTNUMPAD2: {
619 int &HeightDecrement =
620 (ActivePanel == LeftPanel) ? Opt.LeftHeightDecrement : Opt.RightHeightDecrement;
621 if (HeightDecrement > 0) {
622 HeightDecrement--;
623 SetScreenPosition();
624 FrameManager->RefreshFrame();
626 break;
629 case KEY_CTRLLEFT:
630 case KEY_CTRLNUMPAD4: {
631 if (Opt.WidthDecrement < ScrX / 2 - 10) {
632 Opt.WidthDecrement++;
633 SetScreenPosition();
634 FrameManager->RefreshFrame();
637 break;
639 case KEY_CTRLRIGHT:
640 case KEY_CTRLNUMPAD6: {
641 if (Opt.WidthDecrement > -(ScrX / 2 - 10)) {
642 Opt.WidthDecrement--;
643 SetScreenPosition();
644 FrameManager->RefreshFrame();
647 break;
649 case KEY_CTRLCLEAR: {
650 if (Opt.WidthDecrement) {
651 Opt.WidthDecrement = 0;
652 SetScreenPosition();
653 FrameManager->RefreshFrame();
656 break;
658 case KEY_CTRLALTCLEAR: {
659 bool Set = false;
660 if (Opt.LeftHeightDecrement) {
661 Opt.LeftHeightDecrement = 0;
662 Set = true;
664 if (Opt.RightHeightDecrement) {
665 Opt.RightHeightDecrement = 0;
666 Set = true;
668 if (Set) {
669 SetScreenPosition();
670 FrameManager->RefreshFrame();
673 break;
675 case KEY_F9: {
676 ShellOptions(0, nullptr);
677 return TRUE;
679 case KEY_SHIFTF10: {
680 ShellOptions(1, nullptr);
681 return TRUE;
683 default: {
684 if (Key >= KEY_CTRL0 && Key <= KEY_CTRL9)
685 ChangePanelViewMode(ActivePanel, Key - KEY_CTRL0, TRUE);
686 else if (!ActivePanel->ProcessKey(Key))
687 CtrlObject->CmdLine->ProcessKey(Key);
689 break;
693 return TRUE;
696 int FilePanels::ChangePanelViewMode(Panel *Current, int Mode, BOOL RefreshFrame)
698 if (Current && Mode >= VIEW_0 && Mode <= VIEW_9) {
699 Current->SetViewMode(Mode);
700 Current = ChangePanelToFilled(Current, FILE_PANEL);
701 Current->SetViewMode(Mode);
702 // ВНИМАНИЕ! Костыль! Но Работает!
703 SetScreenPosition();
705 if (RefreshFrame)
706 FrameManager->RefreshFrame();
708 return TRUE;
711 return FALSE;
714 Panel *FilePanels::ChangePanelToFilled(Panel *Current, int NewType)
716 if (Current->GetType() != NewType && !Current->ProcessPluginEvent(FE_CLOSE, nullptr)) {
717 Current->Hide();
718 Current = ChangePanel(Current, NewType, FALSE, FALSE);
719 Current->Update(0);
720 Current->Show();
722 if (!GetAnotherPanel(Current)->GetFocus())
723 Current->SetFocus();
726 return (Current);
729 Panel *FilePanels::GetAnotherPanel(Panel *Current)
731 if (Current == LeftPanel)
732 return (RightPanel);
733 else
734 return (LeftPanel);
737 Panel *FilePanels::ChangePanel(Panel *Current, int NewType, int CreateNew, int Force)
739 Panel *NewPanel;
740 SaveScreen *SaveScr = nullptr;
741 // OldType не инициализировался...
742 int OldType = Current->GetType(), X1, Y1, X2, Y2;
743 int OldViewMode, OldSortMode, OldSortOrder, OldSortGroups, OldSelectedFirst, OldDirectoriesFirst;
744 int OldPanelMode, LeftPosition, ChangePosition, OldNumericSort, OldCaseSensitiveSort;
745 int OldFullScreen, OldFocus, UseLastPanel = 0;
746 OldPanelMode = Current->GetMode();
748 if (!Force && NewType == OldType && OldPanelMode == NORMAL_PANEL)
749 return (Current);
751 OldViewMode = Current->GetPrevViewMode();
752 OldFullScreen = Current->IsFullScreen();
753 OldSortMode = Current->GetPrevSortMode();
754 OldSortOrder = Current->GetPrevSortOrder();
755 OldNumericSort = Current->GetPrevNumericSort();
756 OldCaseSensitiveSort = Current->GetPrevCaseSensitiveSort();
757 OldSortGroups = Current->GetSortGroups();
758 OldFocus = Current->GetFocus();
759 OldSelectedFirst = Current->GetSelectedFirstMode();
760 OldDirectoriesFirst = Current->GetPrevDirectoriesFirst();
761 LeftPosition = (Current == LeftPanel);
762 Panel *&LastFilePanel = LeftPosition ? LastLeftFilePanel : LastRightFilePanel;
763 Current->GetPosition(X1, Y1, X2, Y2);
764 ChangePosition = ((OldType == FILE_PANEL && NewType != FILE_PANEL && OldFullScreen)
765 || (NewType == FILE_PANEL
766 && ((OldFullScreen && !FileList::IsModeFullScreen(OldViewMode))
767 || (!OldFullScreen && FileList::IsModeFullScreen(OldViewMode)))));
769 if (!ChangePosition) {
770 SaveScr = Current->SaveScr;
771 Current->SaveScr = nullptr;
774 if (OldType == FILE_PANEL && NewType != FILE_PANEL) {
775 delete Current->SaveScr;
776 Current->SaveScr = nullptr;
778 if (LastFilePanel != Current) {
779 DeletePanel(LastFilePanel);
780 LastFilePanel = Current;
783 LastFilePanel->Hide();
785 if (LastFilePanel->SaveScr) {
786 LastFilePanel->SaveScr->Discard();
787 delete LastFilePanel->SaveScr;
788 LastFilePanel->SaveScr = nullptr;
790 } else {
791 Current->Hide();
792 DeletePanel(Current);
794 if (OldType == FILE_PANEL && NewType == FILE_PANEL) {
795 DeletePanel(LastFilePanel);
796 LastFilePanel = nullptr;
800 if (!CreateNew && NewType == FILE_PANEL && LastFilePanel) {
801 int LastX1, LastY1, LastX2, LastY2;
802 LastFilePanel->GetPosition(LastX1, LastY1, LastX2, LastY2);
804 if (LastFilePanel->IsFullScreen())
805 LastFilePanel->SetPosition(LastX1, Y1, LastX2, Y2);
806 else
807 LastFilePanel->SetPosition(X1, Y1, X2, Y2);
809 NewPanel = LastFilePanel;
811 if (!ChangePosition) {
812 if ((NewPanel->IsFullScreen() && !OldFullScreen)
813 || (!NewPanel->IsFullScreen() && OldFullScreen)) {
814 Panel *AnotherPanel = GetAnotherPanel(Current);
816 if (SaveScr && AnotherPanel->IsVisible() && AnotherPanel->GetType() == FILE_PANEL
817 && AnotherPanel->IsFullScreen())
818 SaveScr->Discard();
820 delete SaveScr;
821 } else
822 NewPanel->SaveScr = SaveScr;
825 if (!OldFocus && NewPanel->GetFocus())
826 NewPanel->KillFocus();
828 UseLastPanel = TRUE;
829 } else
830 NewPanel = CreatePanel(NewType);
832 if (Current == ActivePanel)
833 ActivePanel = NewPanel;
835 if (LeftPosition) {
836 LeftPanel = NewPanel;
837 LastLeftType = OldType;
838 } else {
839 RightPanel = NewPanel;
840 LastRightType = OldType;
843 if (!UseLastPanel) {
844 if (ChangePosition) {
845 if (LeftPosition) {
846 NewPanel->SetPosition(0, Y1, ScrX / 2 - Opt.WidthDecrement, Y2);
847 RightPanel->Redraw();
848 } else {
849 NewPanel->SetPosition(ScrX / 2 + 1 - Opt.WidthDecrement, Y1, ScrX, Y2);
850 LeftPanel->Redraw();
852 } else {
853 NewPanel->SaveScr = SaveScr;
854 NewPanel->SetPosition(X1, Y1, X2, Y2);
857 NewPanel->SetSortMode(OldSortMode);
858 NewPanel->SetSortOrder(OldSortOrder);
859 NewPanel->SetNumericSort(OldNumericSort);
860 NewPanel->SetCaseSensitiveSort(OldCaseSensitiveSort);
861 NewPanel->SetSortGroups(OldSortGroups);
862 NewPanel->SetPrevViewMode(OldViewMode);
863 NewPanel->SetViewMode(OldViewMode);
864 NewPanel->SetSelectedFirstMode(OldSelectedFirst);
865 NewPanel->SetDirectoriesFirst(OldDirectoriesFirst);
868 return (NewPanel);
871 int FilePanels::GetTypeAndName(FARString &strType, FARString &strName)
873 strType = Msg::ScreensPanels;
874 FARString strFullName;
876 switch (ActivePanel->GetType()) {
877 case TREE_PANEL:
878 case QVIEW_PANEL:
879 case FILE_PANEL:
880 case INFO_PANEL:
881 ActivePanel->GetCurName(strFullName);
882 ConvertNameToFull(strFullName, strFullName);
883 break;
886 strName = strFullName;
887 return (MODALTYPE_PANELS);
890 void FilePanels::OnChangeFocus(int f)
892 _OT(SysLog(L"FilePanels::OnChangeFocus(%i)", f));
895 $ 20.06.2001 tran
896 баг с отрисовкой при копировании и удалении
897 не учитывался LockRefreshCount
899 if (f) {
901 $ 22.06.2001 SKV
902 + update панелей при получении фокуса
904 CtrlObject->Cp()->GetAnotherPanel(ActivePanel)->UpdateIfChanged(UIC_UPDATE_FORCE_NOTIFICATION);
905 ActivePanel->UpdateIfChanged(UIC_UPDATE_FORCE_NOTIFICATION);
907 $ 13.04.2002 KM
908 ! ??? Я не понял зачем здесь Redraw, если
909 Redraw вызывается следом во Frame::OnChangeFocus.
911 // Redraw();
912 Frame::OnChangeFocus(1);
916 void FilePanels::DisplayObject()
918 // if ( !Focus )
919 // return;
920 _OT(SysLog(L"[%p] FilePanels::Redraw() {%d, %d - %d, %d}", this, X1, Y1, X2, Y2));
921 CtrlObject->CmdLine->ShowBackground();
923 if (Opt.ShowMenuBar)
924 CtrlObject->TopMenuBar->Show();
926 CtrlObject->CmdLine->Show();
928 MainKeyBar.Refresh(Opt.ShowKeyBar);
930 KeyBarVisible = Opt.ShowKeyBar;
931 #if 1
933 if (LeftPanel->IsVisible())
934 LeftPanel->Show();
936 if (RightPanel->IsVisible())
937 RightPanel->Show();
939 #else
940 Panel *PassivePanel = nullptr;
941 int PassiveIsLeftFlag = TRUE;
943 if (Opt.LeftPanel.Focus) {
944 ActivePanel = LeftPanel;
945 PassivePanel = RightPanel;
946 PassiveIsLeftFlag = FALSE;
947 } else {
948 ActivePanel = RightPanel;
949 PassivePanel = LeftPanel;
950 PassiveIsLeftFlag = TRUE;
953 //! Вначале "показываем" пассивную панель
954 if (PassiveIsLeftFlag) {
955 if (Opt.LeftPanel.Visible) {
956 LeftPanel->Show();
959 if (Opt.RightPanel.Visible) {
960 RightPanel->Show();
962 } else {
963 if (Opt.RightPanel.Visible) {
964 RightPanel->Show();
967 if (Opt.LeftPanel.Visible) {
968 LeftPanel->Show();
972 #endif
975 int FilePanels::ProcessMouse(MOUSE_EVENT_RECORD *MouseEvent)
977 if (!ActivePanel->ProcessMouse(MouseEvent))
978 if (!GetAnotherPanel(ActivePanel)->ProcessMouse(MouseEvent))
979 if (!MainKeyBar.ProcessMouse(MouseEvent))
980 CtrlObject->CmdLine->ProcessMouse(MouseEvent);
982 return TRUE;
985 void FilePanels::ShowConsoleTitle()
987 if (ActivePanel)
988 ActivePanel->SetTitle();
991 void FilePanels::ResizeConsole()
993 Frame::ResizeConsole();
994 CtrlObject->CmdLine->ResizeConsole();
995 MainKeyBar.ResizeConsole();
996 TopMenuBar.ResizeConsole();
997 SetScreenPosition();
998 _OT(SysLog(L"[%p] FilePanels::ResizeConsole() {%d, %d - %d, %d}", this, X1, Y1, X2, Y2));
1001 int FilePanels::FastHide()
1003 return Opt.AllCtrlAltShiftRule & CASR_PANEL;
1006 void FilePanels::Refresh()
1009 $ 31.07.2001 SKV
1010 Вызовем так, а не Frame::OnChangeFocus,
1011 который из этого и позовётся.
1013 // Frame::OnChangeFocus(1);
1014 OnChangeFocus(1);
1017 void FilePanels::GoToFile(const wchar_t *FileName)
1019 if (FirstSlash(FileName)) {
1020 FARString ADir, PDir;
1021 Panel *PassivePanel = GetAnotherPanel(ActivePanel);
1022 int PassiveMode = PassivePanel->GetMode();
1024 if (PassiveMode == NORMAL_PANEL) {
1025 PassivePanel->GetCurDir(PDir);
1026 AddEndSlash(PDir);
1029 int ActiveMode = ActivePanel->GetMode();
1031 if (ActiveMode == NORMAL_PANEL) {
1032 ActivePanel->GetCurDir(ADir);
1033 AddEndSlash(ADir);
1036 FARString strNameFile = PointToName(FileName);
1037 FARString strNameDir = FileName;
1038 CutToSlash(strNameDir);
1040 $ 10.04.2001 IS
1041 Не делаем SetCurDir, если нужный путь уже есть на открытых
1042 панелях, тем самым добиваемся того, что выделение с элементов
1043 панелей не сбрасывается.
1045 BOOL AExist = (ActiveMode == NORMAL_PANEL) && !StrCmp(ADir, strNameDir);
1046 BOOL PExist = (PassiveMode == NORMAL_PANEL) && !StrCmp(PDir, strNameDir);
1048 // если нужный путь есть на пассивной панели
1049 if (!AExist && PExist)
1050 ProcessKey(KEY_TAB);
1052 if (!AExist && !PExist)
1053 ActivePanel->SetCurDir(strNameDir, TRUE);
1055 ActivePanel->GoToFile(strNameFile);
1056 // всегда обновим заголовок панели, чтобы дать обратную связь, что
1057 // Ctrl-F10 обработан
1058 ActivePanel->SetTitle();
1062 int FilePanels::GetMacroMode()
1064 switch (ActivePanel->GetType()) {
1065 case TREE_PANEL:
1066 return MACRO_TREEPANEL;
1067 case QVIEW_PANEL:
1068 return MACRO_QVIEWPANEL;
1069 case INFO_PANEL:
1070 return MACRO_INFOPANEL;
1071 default:
1072 return MACRO_SHELL;