Merge pull request #2512 from spnethw/tmppanel_fix_menu_from_file_list_crash
[far2l.git] / multiarc / src / ArcProc.cpp
blob4df4268f12be4fb0b169910ce47e78efc07ff430
1 #include "MultiArc.hpp"
2 #include "marclng.hpp"
3 #include <errno.h>
5 BOOL PluginClass::GetFormatName(std::string &FormatName, std::string &DefExt)
7 FormatName.clear();
8 DefExt.clear();
9 return ArcPlugin->GetFormatName(ArcPluginNumber, ArcPluginType, FormatName, DefExt);
12 BOOL PluginClass::GetFormatName(std::string &FormatName)
14 FormatName.clear();
15 std::string TempDefExt;
16 return ArcPlugin->GetFormatName(ArcPluginNumber, ArcPluginType, FormatName, TempDefExt);
20 std::string PluginClass::GetCommandFormat(int Command)
22 std::string ArcFormat;
23 if (!GetFormatName(ArcFormat))
24 return std::string();
25 std::string CommandFormat;
26 ArcPlugin->GetDefaultCommands(ArcPluginNumber, ArcPluginType, Command, CommandFormat);
27 return KeyFileReadSection(INI_LOCATION, ArcFormat).GetString(CmdNames[Command], CommandFormat.c_str());
30 int PluginClass::DeleteFiles(struct PluginPanelItem *PanelItem, int ItemsNumber, int OpMode)
32 //char Command[MA_MAX_SIZE_COMMAND_NAME], AllFilesMask[MA_MAX_SIZE_COMMAND_NAME];
33 std::string Command, AllFilesMask;
34 if (ItemsNumber == 0)
35 return FALSE;
36 if ((OpMode & OPM_SILENT) == 0) {
37 const char *MsgItems[] = {GetMsg(MDeleteTitle), GetMsg(MDeleteFiles), GetMsg(MDeleteDelete),
38 GetMsg(MDeleteCancel)};
39 std::string Msg;
40 if (ItemsNumber == 1) {
41 const auto &NameMsg = FormatMessagePath(PanelItem[0].FindData.cFileName, false);
42 Msg = StrPrintf(GetMsg(MDeleteFile), NameMsg.c_str());
43 MsgItems[1] = Msg.c_str();
45 if (Info.Message(Info.ModuleNumber, 0, NULL, MsgItems, ARRAYSIZE(MsgItems), 2) != 0)
46 return FALSE;
48 if (ItemsNumber > 1) {
49 Msg = StrPrintf(GetMsg(MDeleteNumberOfFiles), ItemsNumber);
50 MsgItems[1] = Msg.c_str();
51 if (Info.Message(Info.ModuleNumber, FMSG_WARNING, NULL, MsgItems, ARRAYSIZE(MsgItems), 2) != 0)
52 return FALSE;
55 Command = GetCommandFormat(CMD_DELETE);
56 AllFilesMask = GetCommandFormat(CMD_ALLFILESMASK);
57 int IgnoreErrors = (CurArcInfo.Flags & AF_IGNOREERRORS);
58 ArcCommand ArcCmd(PanelItem, ItemsNumber, Command, ArcName, CurDir, "", AllFilesMask, IgnoreErrors, CMD_DELETE, 0,
59 CurDir, ItemsInfo.Codepage);
60 if (!IgnoreErrors && ArcCmd.GetExecCode() != 0)
61 return FALSE;
62 if (Opt.UpdateDescriptions)
63 for (int I = 0; I < ItemsNumber; I++)
64 PanelItem[I].Flags|= PPIF_PROCESSDESCR;
65 return TRUE;
68 int PluginClass::ProcessHostFile(struct PluginPanelItem *PanelItem, int ItemsNumber, int OpMode)
70 struct ArcCmdMenuData
72 int Msg, Cmd;
74 static const ArcCmdMenuData MenuData[] = {
75 {MArcCmdTest, CMD_TEST },
76 {MArcCmdComment, CMD_COMMENT },
77 {MArcCmdCommentFiles, CMD_COMMENTFILES},
78 {MArcCmdSFX, CMD_SFX },
79 {MArcCmdRecover, CMD_RECOVER },
80 {MArcCmdProtect, CMD_PROTECT },
81 {MArcCmdLock, CMD_LOCK },
84 std::string Command, AllFilesMask;
85 int CommandType;
86 int ExitCode = 0;
88 while (1) {
89 struct FarMenuItemEx MenuItems[ARRAYSIZE(MenuData)];
91 ZeroFill(MenuItems);
92 MenuItems[ExitCode].Flags = MIF_SELECTED;
94 int Count = 0;
95 for (size_t i = 0; i < ARRAYSIZE(MenuData); i++) {
96 Command = GetCommandFormat(MenuData[i].Cmd);
97 if (!Command.empty()) {
98 MenuItems[Count].Text.TextPtr = GetMsg(MenuData[i].Msg);
99 MenuItems[Count].Flags|= MIF_USETEXTPTR;
100 MenuItems[Count++].UserData = MenuData[i].Cmd;
104 if (!Count) {
105 Count = 1;
106 MenuItems[0].UserData = 0xFFFFFFFF;
109 int BreakCode;
110 int BreakKeys[2] = {VK_F4, 0};
111 ExitCode = Info.Menu(Info.ModuleNumber, -1, -1, 0, FMENU_USEEXT | FMENU_WRAPMODE,
112 GetMsg(MArcCmdTitle), GetMsg(MSelectF4), "ArcCmd", BreakKeys, &BreakCode,
113 (FarMenuItem *)MenuItems, Count);
114 if (ExitCode >= 0) {
115 if (BreakCode == 0) // F4 pressed
117 MenuItems[0].Flags&= ~MIF_USETEXTPTR;
118 std::string FormatName;
119 GetFormatName(FormatName);
120 CharArrayCpyZ(MenuItems[0].Text.Text, FormatName.c_str());
121 ConfigCommands(FormatName, 2 + MenuData[ExitCode].Cmd * 2);
122 continue;
124 CommandType = (int)MenuItems[ExitCode].UserData;
125 if (MenuItems[ExitCode].UserData == 0xFFFFFFFF)
126 return FALSE;
127 } else
128 return FALSE;
129 break;
132 WINPORT(FlushConsoleInputBuffer)(NULL); // GetStdHandle(STD_INPUT_HANDLE));
134 Command = GetCommandFormat(CommandType);
135 AllFilesMask = GetCommandFormat(CMD_ALLFILESMASK);
136 int IgnoreErrors = (CurArcInfo.Flags & AF_IGNOREERRORS);
137 std::string Password;
139 int AskVolume = (OpMode & (OPM_FIND | OPM_VIEW | OPM_EDIT | OPM_QUICKVIEW)) == 0 && CurArcInfo.Volume
140 && *CurDir == 0 && ExitCode == 0;
141 struct PluginPanelItem MaskPanelItem;
143 if (AskVolume) {
144 const auto &NameMsg = FormatMessagePath(ArcName.c_str(), true);
145 const auto &VolMsg = StrPrintf(GetMsg(MExtrVolume), NameMsg.c_str());
146 const char *MsgItems[] = {"", VolMsg.c_str(), GetMsg(MExtrVolumeAsk1), GetMsg(MExtrVolumeAsk2),
147 GetMsg(MExtrVolumeSelFiles), GetMsg(MExtrAllVolumes)};
148 int MsgCode = Info.Message(Info.ModuleNumber, 0, NULL, MsgItems, ARRAYSIZE(MsgItems), 2);
149 if (MsgCode < 0)
150 return -1;
151 if (MsgCode == 1) {
152 ZeroFill(MaskPanelItem);
153 CharArrayCpyZ(MaskPanelItem.FindData.cFileName, AllFilesMask.c_str());
154 if (ItemsInfo.Encrypted)
155 MaskPanelItem.Flags = F_ENCRYPTED;
156 PanelItem = &MaskPanelItem;
157 ItemsNumber = 1;
161 if (Command.find("%%P") != std::string::npos)
162 for (int I = 0; I < ItemsNumber; I++)
163 if ((PanelItem[I].Flags & F_ENCRYPTED)
164 || (ItemsInfo.Encrypted
165 && (PanelItem[I].FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))) {
166 if (!GetPassword(Password, FSF.PointToName((char *)ArcName.c_str())))
167 return FALSE;
168 break;
171 ArcCommand ArcCmd(PanelItem, ItemsNumber, Command, ArcName, CurDir,
172 Password, AllFilesMask, IgnoreErrors, CommandType, 0, CurDir, ItemsInfo.Codepage);
173 return IgnoreErrors || ArcCmd.GetExecCode() == 0;
176 int __cdecl FormatSort(struct FarMenuItemEx *Item1, struct FarMenuItemEx *Item2)
178 return strcasecmp(Item1->Text.Text, Item2->Text.Text);
181 bool PluginClass::SelectFormat(std::string &ArcFormat, int AddOnly)
183 typedef int(__cdecl * FCmp)(const void *, const void *);
184 struct FarMenuItemEx *MenuItems = NULL, *NewMenuItems;
185 int MenuItemsNumber = 0;
186 std::string Format, DefExt;
187 int BreakCode;
188 int BreakKeys[] = {VK_F4, VK_RETURN, 0};
189 int ExitCode;
191 BreakKeys[1] = (AddOnly) ? 0 : VK_RETURN;
193 while (1) {
194 for (int i = 0; i < ArcPlugin->FmtCount(); i++) {
195 for (int j = 0;; j++) {
196 if (!ArcPlugin->GetFormatName(i, j, Format, DefExt))
197 break;
199 if (AddOnly) // Only add to archive?
201 std::string CmdAdd;
202 ArcPlugin->GetDefaultCommands(i, j, CMD_ADD, CmdAdd);
203 CmdAdd = KeyFileReadSection(INI_LOCATION, Format).GetString(CmdNames[CMD_ADD], CmdAdd.c_str());
204 if (CmdAdd.empty())
205 continue;
208 NewMenuItems = (struct FarMenuItemEx *)realloc(MenuItems,
209 (MenuItemsNumber + 1) * sizeof(struct FarMenuItemEx));
210 if (NewMenuItems == NULL) {
211 free(MenuItems);
212 return false;
214 MenuItems = NewMenuItems;
215 ZeroFill(MenuItems[MenuItemsNumber]);
216 MenuItems[MenuItemsNumber].UserData = MAKEWPARAM((WORD)i, (WORD)j);
217 CharArrayCpyZ(MenuItems[MenuItemsNumber].Text.Text, Format.c_str());
218 MenuItems[MenuItemsNumber].Flags =
219 ((MenuItemsNumber == 0 && ArcFormat.empty()) || !strcasecmp(ArcFormat.c_str(), Format.c_str()))
220 ? MIF_SELECTED : 0;
221 MenuItemsNumber++;
224 if (MenuItemsNumber == 0)
225 return false;
227 FSF.qsort(MenuItems, MenuItemsNumber, sizeof(struct FarMenuItemEx), (FCmp)FormatSort);
229 DWORD Flags = FMENU_AUTOHIGHLIGHT | FMENU_USEEXT;
230 if (!Opt.AdvFlags.MenuWrapMode)
231 Flags|= FMENU_WRAPMODE;
232 else if (Opt.AdvFlags.MenuWrapMode == 2) {
233 CONSOLE_SCREEN_BUFFER_INFO csbi;
234 WINPORT(GetConsoleScreenBufferInfo)(NULL, &csbi); // GetStdHandle(STD_OUTPUT_HANDLE)
235 if (csbi.dwSize.Y - 6 >= MenuItemsNumber)
236 Flags|= FMENU_WRAPMODE;
238 ExitCode = Info.Menu(Info.ModuleNumber, -1, -1, 0, Flags, GetMsg(MSelectArchiver), GetMsg(MSelectF4),
239 NULL, BreakKeys, &BreakCode, (struct FarMenuItem *)MenuItems, MenuItemsNumber);
240 if (ExitCode >= 0) {
241 CharArrayAssignToStr(ArcFormat, MenuItems[ExitCode].Text.Text);
242 if ((BreakCode >= 0 && BreakCode <= 1) || !AddOnly) // F4 or Enter pressed
243 ConfigCommands(ArcFormat, 2, TRUE,
244 LOWORD(MenuItems[ExitCode].UserData), HIWORD(MenuItems[ExitCode].UserData));
245 else
246 break;
247 } else
248 break;
249 free(MenuItems);
250 MenuItems = NULL;
251 MenuItemsNumber = 0;
253 if (MenuItems)
254 free(MenuItems);
255 return ExitCode >= 0;
258 bool PluginClass::FormatToPlugin(const std::string &Format, int &PluginNumber, int &PluginType)
260 std::string PluginFormat, DefExt;
261 for (int i = 0; i < ArcPlugin->FmtCount(); i++) {
262 for (int j = 0;; j++) {
263 if (!ArcPlugin->GetFormatName(i, j, PluginFormat, DefExt))
264 break;
265 if (!strcasecmp(PluginFormat.c_str(), Format.c_str())) {
266 PluginNumber = i;
267 PluginType = j;
268 return true;
272 return false;
275 SHAREDSYMBOL int WINAPI _export Configure(int ItemNumber);
277 int PluginClass::ProcessKey(int Key, unsigned int ControlState)
279 if ((ControlState & PKF_ALT) && Key == VK_F6) {
280 // HANDLE hScreen=Info.SaveScreen(0,0,-1,-1);
281 if (strstr(ArcName.c_str(), /*"FarTmp"*/ "FTMP") == NULL) //$AA какая-то бяка баловалась
283 std::string CurDir = ArcName;
284 const size_t Slash = CurDir.rfind(GOOD_SLASH);
285 if (Slash != std::string::npos) {
286 CurDir.resize(Slash);
287 if (sdc_chdir(CurDir.c_str()))
288 fprintf(stderr, "sdc_chdir('%s') - %u\n", CurDir.c_str(), errno);
291 struct PanelInfo PInfo;
292 Info.Control(this, FCTL_GETPANELINFO, &PInfo);
293 GetFiles(PInfo.SelectedItems, PInfo.SelectedItemsNumber, FALSE, PInfo.CurDir, OPM_SILENT);
294 // Info.RestoreScreen(hScreen);
295 Info.Control(this, FCTL_UPDATEPANEL, (void *)1);
296 Info.Control(this, FCTL_REDRAWPANEL, NULL);
297 Info.Control(this, FCTL_UPDATEANOTHERPANEL, (void *)1);
298 Info.Control(this, FCTL_REDRAWANOTHERPANEL, NULL);
299 return TRUE;
300 } else if (ControlState == (PKF_ALT | PKF_SHIFT) && Key == VK_F9) {
301 Configure(0);
302 return TRUE;
304 return FALSE;