View Issue Details

IDProjectCategoryView StatusLast Update
0001789WishesMacropublic2014-01-22 10:15
ReporterMaximus Assigned Tovskirdin  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status assignedResolutionopen 
Product Version3.0 
Summary0001789: Функция для управления быстрым фильтром в списках (CtrlAltF)
DescriptionХочется функцию Menu.Filter чтобы как минимум узнать состояние фильтра, а в идеале и порулить им.

Еще хорошо бы "Menu.Count" чтобы узнать количество видимых строк.

Предлагаются такие параметры
Menu.Filter(Action[,Filter])

значения Action:
0 - вернуть текущее состояние фильтра (bitmask)
    0x1 - фильтр сейчас включен
    0x2 - строка фильтра не пустая
1 - вернуть текущую строку фильтра
2 - включить фильтр
3 - выключить фильтр
4 - установить в фильтре строку <Filter>, если параметр <Filter> опущен - установить пустую строку.
TagsNo tags attached.
Build

Activities

Maximus

2011-06-02 09:49

reporter   bugnote:0007117

Last edited: 2011-06-02 14:16

хотя не, Action=1 наверное нехорошо (строку возвращает, в отличие от...)
Наверное вместо него лучше Menu.CurFilter

то есть остаются значения Action:
0 - вернуть текущее состояние фильтра (bitmask)
    0x1 - фильтр сейчас включен
    0x2 - заблокирован
    0x4 - строка фильтра не пустая
1 - включить фильтр
2 - выключить фильтр
3 - заблокировать
4 - разблокировать
5 - установить в фильтре строку <Filter>, если параметр <Filter> опущен - установить пустую строку
6 - подправить высоту списка под количество элементов

Все кроме Action=0 возвращают 1 в случае успеха, иначе 0.

JohnDoe

2011-06-02 15:55

updater   bugnote:0007118

Last edited: 2011-06-02 15:57

>Наверное вместо него лучше Menu.CurFilter
Может лучше разбить по двум полноценным функциям?
Одна бы оперировала строками (Menu.FilterStr), другая всем остальным (Menu.Filter).
?

И что значит "заблокировать фильтр"?

Maximus

2011-06-02 18:53

reporter   bugnote:0007120

Может две функции и лучше, мне без разницы.
Что по твоему должна возвращать Menu.FilterStr("новый фильтр")?

Заблокировать - значит CtrlAltL :) В коде поковыряешься - и не то еще найдешь.

btw, патчик на Menu.Filter & Menu.CurFilter уже почти готов

JohnDoe

2011-06-03 17:18

updater   bugnote:0007130

Last edited: 2011-06-03 18:51

>Заблокировать - значит CtrlAltL
От слова "Lock"...
Я бы назвал это скорее "зафиксировать".

>Что по твоему должна возвращать Menu.FilterStr("новый фильтр")?
Предыдущее значение фильтра.

P.S.
Вероятно одним параметром не обойтись...

------
S=Menu.FilterStr(Action[,Str])
Action
 1 - установить в качестве фильтра строку Str. Параметр Str можно опустить, это равнозначно указанию пустой строки.
 -1 - не менять фильтр (получить текущее значение)

Функция возвращает предыдущее значение строки фильтра.
В случае ошибки возвращается -1 (например ошибка в параметрах, или функция вызвана не из меню/списка).

Замечания.
 При Action=1:
 Если фильтр был выключен, то вызов функции включает его, даже если параметр Str опущен, или равен пустой строке.
 Если фильтр был "заблокирован" - то вызов функции меняет строку, но оставляет заблокированность.

JohnDoe

2011-06-03 17:42

updater   bugnote:0007131

Last edited: 2011-06-03 18:37

>0 - вернуть текущее состояние фильтра (bitmask)
Битовая маска (при Action=0) меня несколько смущает.
Что если сделать как-то так:

N=Menu.FilterStatus(Action[,Status])
Action
 1 - включить
 0 - выключить
 -1 - не менять (вернуть текущее значение)

Status
 0 - включен/выключен
 1 - активен/заблокирован (зафиксирован)

...возможно стоит добавить дополнительные свойства (недоступные для изменения).
 2 - строка фильтра непуста
 3 - есть отфильтрованные элементы

Функция возвращает предыдущее состояние режима.
В случае неудачи возвращается -1 (например, ошибка в параметрах, или функция вызвана не из меню/списка).

Maximus

2011-06-03 18:50

reporter   bugnote:0007135

Ты вот мне объясни, как ты отличишь результат Menu.FilterStr
ошибка (-1) и предыдущий фильтр ("-1")?

%l=-1; $if (%l=="-1") MsgBox("","Equal") $else MsgBox("","Not equal") $end

JohnDoe

2011-06-03 18:53

updater   bugnote:0007136

Last edited: 2011-06-03 18:55

Вероятно прямо - никак (только косвенно).
Но ведь то же самое и в вашей реализации (с Menu.CurFilter)?

Maximus

2011-06-03 19:02

reporter   bugnote:0007138

Мне - без разницы. Пока что заинтересованных лиц не видно.

В моей редакции ошибку можно отловить при установке строки фильтра. О чем я речь и веду. Menu.CurFilter на ошибки тестировать не интересно, поскольку можно предварительно проверить статус фильтра (Menu.Filter ошибки возвращает).

Чем не нравится битовая маска - не понимаю. В макросах фара куча функций возвращающая маски.
И да, я не написал, но если фильтр выключен - то Menu.Filter(0) возвращает 0, чтобы не париться с проверками битов.

JohnDoe

2011-06-03 19:19

updater   bugnote:0007139

Last edited: 2011-06-03 19:30

>...поскольку можно предварительно проверить статус фильтра
У меня точно так же можно.
Кстати это ведь не единственная функция в макроязыке, возвращающая "предыдущее значение" при установке нового. А масса функций вообще не обрабатывают ошибки...

Итог: то, что ошибку при определённых условиях можно спутать со значением это не хорошо, но на общем фоне ... нормально.
Как вы сами и пишете, при желании возможную ошибку можно обработать отдельно.

>если фильтр выключен - то Menu.Filter(0) возвращает 0, чтобы не париться с проверками битов.
А разве те биты вообще могут иметь смысл при выключенном фильтре?
Ведь если фильтр выключить/включить то всё сбрасывается.

>Чем не нравится битовая маска - не понимаю.
Тем что тут легко обойтись без неё, а её использование не даёт нам никаких преимуществ.
Недавно на форуме всплывало - многие не умеют как следуют работать с битами.
Всё таки макроязык он не для программистов.

JohnDoe

2011-06-03 19:48

updater   bugnote:0007141

Last edited: 2011-06-03 19:57

>Итог: то, что ошибку при определённых условиях можно спутать со значением это не хорошо...
Как бы то ни было я признаю что в вашей редакции с этим более аккуратно.

Но в вашей редакции мне (помимо битовой маски) не нравится то что одна функция выполняет черезчур много действий, причём довольно разнородных.


P.S.
>Пока что заинтересованных лиц не видно.
Как обычно :-)
Надо на форуме обсуждать - там хоть народу больше.

JohnDoe

2011-06-04 00:24

updater   bugnote:0007142

Ещё по теме: недавно предлагался "масочный" режим фильтра: 0001752
Впрочем для наших макрофункций это мало что изменит.

Maximus

2011-06-05 21:31

reporter  

vmenu_macro.diff (14,488 bytes)   
Index: vmenu.hpp
===================================================================
--- vmenu.hpp	(revision 6311)
+++ vmenu.hpp	(working copy)
@@ -89,6 +89,7 @@
 	VMENU_MOUSEREACTION        =0x02000000, // ���������� �� �������� ��? (�������� ����� ��� ���������� ������� ��?)
 	VMENU_DISABLED             =0x04000000, //
 	VMENU_NOMERGEBORDER        =0x08000000, //
+	VMENU_REFILTERREQUIRED     =0x10000000, // ����� ���������� ��������� ������� �����
 };
 
 class Dialog;
@@ -210,6 +211,7 @@
 		int SelectPos;
 		int TopPos;
 		int MaxHeight;
+		bool WasAutoHeight;
 		int MaxLength;
 		int BoxType;
 		bool PrevCursorVisible;
@@ -324,6 +326,7 @@
 		int  FindItem(int StartIndex,const wchar_t *Pattern,UINT64 Flags=0);
 		void RestoreFilteredItems();
 		void FilterStringUpdated(bool bLonger);
+		void FilterUpdateHeight(bool bShrink=false);
 		void SetFilterEnabled(bool bEnabled) { bFilterEnabled=bEnabled; };
 		void SetFilterLocked(bool bLocked) { bFilterEnabled=bLocked; };
  		bool AddToFilter(const wchar_t *str);
Index: vmenu.cpp
===================================================================
--- vmenu.cpp	(revision 6311)
+++ vmenu.cpp	(working copy)
@@ -69,6 +69,7 @@
 	strTitle(Title),
 	SelectPos(-1),
 	TopPos(0),
+	WasAutoHeight(false),
 	MaxLength(0),
 	BoxType(DOUBLE_BOX),
 	ParentDialog(ParentDialog),
@@ -446,7 +447,7 @@
 	if (PosAdd < 0)
 		PosAdd = 0;
 
-	SetFlags(VMENU_UPDATEREQUIRED);
+	SetFlags(VMENU_UPDATEREQUIRED|(bFilterEnabled?VMENU_REFILTERREQUIRED:0));
 
 	if (!(ItemCount & 255))
 	{
@@ -512,7 +513,7 @@
 
 		UpdateItemFlags(NewItem->Index, MItem.Flags);
 
-		SetFlags(VMENU_UPDATEREQUIRED);
+		SetFlags(VMENU_UPDATEREQUIRED|(bFilterEnabled?VMENU_REFILTERREQUIRED:0));
 
 		return TRUE;
 	}
@@ -649,47 +650,172 @@
 
 	ItemHiddenCount=0;
 
-	if (SelectPos < 0)
-		SetSelectPos(0,1);
+	FilterUpdateHeight();
+
+	// ��������, � �� � ������ ����� ������ ����� �������� ��� ���� �����
+	FarListPos pos={SelectPos < 0 ? 0 : SelectPos,-1};
+	SetSelectPos(&pos);
 }
 
 void VMenu::FilterStringUpdated(bool bLonger)
 {
+	int PrevSeparator = -1, PrevGroup = -1;
+	int UpperVisible = -1, LowerVisible = -2;
+	bool bBottomMode = false;
 
+	if (SelectPos > 0)
+	{
+		// ���������, � ������ ��� ������ ����� ���������� ������
+		int TopVisible = GetVisualPos(TopPos);
+		int SelectedVisible = GetVisualPos(SelectPos);
+		int BottomVisible = (TopVisible+MaxHeight > GetShowItemCount()) ? (TopVisible+MaxHeight-1) : (GetShowItemCount()-1);
+		if (SelectedVisible >= ((TopVisible+BottomVisible)>>1))
+			bBottomMode = true;
+	}
+
 	if (bLonger)
 	{
 		//������ ������ ���������
 		for (int i=0; i < ItemCount; i++)
 		{
-			if (ItemIsVisible(Item[i]->Flags) && !StrStrI(Item[i]->strName, strFilter))
+			// ��� ����� ��������� ����� �� �����������
+			if (ItemIsVisible(Item[i]->Flags))
 			{
-				Item[i]->Flags |= LIF_HIDDEN;
-				ItemHiddenCount++;
-				if (SelectPos == i)
+				if (Item[i]->Flags & LIF_SEPARATOR)
 				{
-					Item[i]->Flags &= ~LIF_SELECTED;
-					SelectPos = -1;
+					// � �������� ������ ��� ������� ����, ���������� ����� ������� - �� �����
+					if (PrevSeparator != -1)
+					{
+						Item[PrevSeparator]->Flags |= LIF_HIDDEN;
+						ItemHiddenCount++;
+					}
+					if (Item[i]->strName.IsEmpty() && PrevGroup == -1)
+					{
+						Item[i]->Flags |= LIF_HIDDEN;
+						ItemHiddenCount++;
+						PrevSeparator = -1;
+					}
+					else
+					{
+						PrevSeparator = i;
+					}
 				}
+				else if (!StrStrI(Item[i]->strName, strFilter))
+				{
+					Item[i]->Flags |= LIF_HIDDEN;
+					ItemHiddenCount++;
+					if (SelectPos == i)
+					{
+						Item[i]->Flags &= ~LIF_SELECTED;
+						SelectPos = -1;
+						LowerVisible = -1;
+					}
+				}
+				else
+				{
+					PrevGroup = i;
+					if (LowerVisible == -2)
+					{
+						if (ItemCanHaveFocus(Item[i]->Flags))
+							UpperVisible = i;
+					}
+					else if (LowerVisible == -1)
+					{
+						if (ItemCanHaveFocus(Item[i]->Flags))
+							LowerVisible = i;
+					}
+					// ���� ���������� - ������� ������
+					if (PrevSeparator != -1)
+						PrevSeparator = -1;
+				}
 			}
 		}
+		// � �������� ������ ��� ������� ����, ���������� ����� ������� - �� �����
+		if (PrevSeparator != -1)
+		{
+			Item[PrevSeparator]->Flags |= LIF_HIDDEN;
+			ItemHiddenCount++;
+		}
 	}
 	else
 	{
 		//������ ������ ����������
 		for (int i=0; i < ItemCount; i++)
 		{
-			if (!ItemIsVisible(Item[i]->Flags) && StrStrI(Item[i]->strName, strFilter))
+			if (!ItemIsVisible(Item[i]->Flags))
 			{
-				Item[i]->Flags &= ~LIF_HIDDEN;
-				ItemHiddenCount--;
+				if (Item[i]->Flags & LIF_SEPARATOR)
+				{
+					PrevSeparator = i;
+				}
+				else if (StrStrI(Item[i]->strName, strFilter))
+				{
+					Item[i]->Flags &= ~LIF_HIDDEN;
+					ItemHiddenCount--;
+				}
 			}
+			
+
+			if (ItemIsVisible(Item[i]->Flags))
+			{
+				if (Item[i]->Flags & LIF_SEPARATOR)
+				{
+					PrevGroup = -1;
+					if ((PrevSeparator != -1))
+						PrevSeparator = -1;
+				}
+				else
+				{
+					if (PrevSeparator != -1)
+					{
+						if (!Item[PrevSeparator]->strName.IsEmpty() || PrevGroup != -1)
+						{
+							// ���������� ����� ����� ������ ������� �� ����
+							Item[PrevSeparator]->Flags &= ~LIF_HIDDEN;
+							ItemHiddenCount--;
+						}
+						PrevSeparator = -1;
+					}
+					PrevGroup = i;
+				}
+			}
 		}
+
+		FilterUpdateHeight();
 	}
 
-	if (SelectPos<0)
-		SetSelectPos(0,1);
+	if (GetShowItemCount()>0)
+	{
+		// ��������, � �� � ������ ����� ������ ����� �������� ��� ���� �����
+		FarListPos pos={SelectPos,-1};
+		if (SelectPos<0)
+		{
+			pos.SelectPos = bBottomMode ? ((LowerVisible>0) ? LowerVisible : UpperVisible) : UpperVisible;
+			if (pos.SelectPos == -1)
+				pos.SelectPos = bBottomMode ? VisualPosToReal(GetShowItemCount()-1) : 0;
+		}
+		SetSelectPos(&pos);
+	}
 }
 
+void VMenu::FilterUpdateHeight(bool bShrink)
+{
+	if (WasAutoHeight)
+	{
+		int NewY2;
+		if (MaxHeight && MaxHeight<GetShowItemCount())
+			NewY2 = Y1 + MaxHeight + 1;
+		else
+			NewY2 = Y1 + GetShowItemCount() + 1;
+		if (NewY2 > ScrY)
+			NewY2 = ScrY;
+		if (NewY2 > Y2 || (bShrink && NewY2 < Y2))
+		{
+			SetPosition(X1,Y1,X2,NewY2);
+		}
+	}
+}
+
 bool VMenu::IsFilterEditKey(int Key)
 {
 	return (Key>=(int)KEY_SPACE && Key<0xffff) || Key==KEY_BS;
@@ -902,6 +1028,118 @@
 			return 0;
 		}
 
+		case MCODE_F_MENU_FILTER:
+		{
+			__int64 RetValue = 0;
+			/*
+			Action
+			  0 - �����
+			    Mode
+			      -1 - (�� �������) ������ 1 ���� ����� ��� �����, 0 - ����� �����
+				   1 - ����� �����, ���� ����� ��� ����� - ����� �� ������
+				   0 - ����� �����
+			  1 - ������ ������ ������
+			    Mode
+			      -1 - (�� �������) ������ 1 ���� ����� ������ ������������, 0 - ����� ����� ���� � ���������
+				   1 - ������������ �����
+				   0 - ������� ������ ������
+			  2 - ������ 1 ���� ����� ����� � ������ ������ �� �����
+			  3 - ������ ��������� ������������ (�������) �����\
+			  4 - (�� �������) ��������� ����� ������ ��� ��������� ���������
+			*/
+			switch (iParam)
+			{
+				case 0:
+					switch ((INT_PTR)vParam)
+					{
+						case 0:
+						case 1:
+							if (bFilterEnabled != ((INT_PTR)vParam == 1))
+							{
+								bFilterEnabled=((INT_PTR)vParam == 1);
+								bFilterLocked=false;
+								strFilter.Clear();
+								if (!vParam)
+									RestoreFilteredItems();
+								DisplayObject();
+							}
+							RetValue = 1;
+							break;
+						case -1:
+							RetValue = bFilterEnabled ? 1 : 0;
+							break;
+					}
+					break;
+
+				case 1:
+					switch ((INT_PTR)vParam)
+					{
+						case 0:
+						case 1:
+							bFilterLocked=((INT_PTR)vParam == 1);
+							DisplayObject();
+							RetValue = 1;
+							break;
+						case -1:
+							RetValue = bFilterLocked ? 1 : 0;
+							break;
+					}
+					break;
+
+				case 2:
+					RetValue = (bFilterEnabled && !strFilter.IsEmpty()) ? 1 : 0;
+					break;
+
+				case 3:
+					RetValue = ItemHiddenCount;
+					break;
+
+				case 4:
+					FilterUpdateHeight(true);
+					DisplayObject();
+					RetValue = 1;
+					break;
+			}
+			return RetValue;
+		}
+		case MCODE_F_MENU_FILTERSTR:
+		{
+			/*
+			Action
+			  0 - (�� �������) ������ ����� ������, ���� ����� �����
+			  1 - ��������� � ������ ������ S.
+			      ���� ����� �� �� ����� - ������ ���, ����� ������� �� ��������, �� �����������.
+				  ��������� �������� ������� ������ ������.
+			*/
+			switch (iParam)
+			{
+				case 0:
+					if (bFilterEnabled)
+					{
+						*(string *)vParam = strFilter;
+						return 1;
+					}
+					break;
+				case 1:
+					if (!bFilterEnabled)
+						bFilterEnabled=true;
+					bool prevLocked = bFilterLocked;
+					bFilterLocked = false;
+					RestoreFilteredItems();
+					string oldFilter = strFilter;
+					strFilter.Clear();
+					if (vParam!=nullptr)
+						AddToFilter(((string *)vParam)->CPtr());
+					FilterStringUpdated(true);
+					bFilterLocked = prevLocked;
+					DisplayObject();
+					*(string *)vParam = oldFilter;
+					return 1;
+			}
+
+			return 0;
+		}
+
 	}
 
 	return 0;
@@ -1027,7 +1265,8 @@
 		case KEY_CTRLHOME:     case KEY_CTRLNUMPAD7:
 		case KEY_CTRLPGUP:     case KEY_CTRLNUMPAD9:
 		{
-			SetSelectPos(0,1);
+			FarListPos pos={0,-1};
+			SetSelectPos(&pos);
 			ShowMenu(true);
 			break;
 		}
@@ -1601,8 +1840,10 @@
 			}
 		}
 
+		WasAutoHeight = false;
 		if (Y2 <= 0)
 		{
+			WasAutoHeight = true;
 			if (MaxHeight && MaxHeight<GetShowItemCount())
 				Y2 = Y1 + MaxHeight + 1;
 			else
@@ -1662,6 +1903,17 @@
 	ClearFlags(VMENU_UPDATEREQUIRED);
 	Modal::ExitCode = -1;
 
+	if (CheckFlags(VMENU_REFILTERREQUIRED)!=0)
+	{
+		if (bFilterEnabled)
+		{
+			RestoreFilteredItems();
+			if (!strFilter.IsEmpty())
+				FilterStringUpdated(true);
+		}
+		ClearFlags(VMENU_REFILTERREQUIRED);
+	}
+
 	SetCursorType(0,10);
 
 	if (!CheckFlags(VMENU_LISTBOX) && !SaveScr)
@@ -1676,6 +1928,8 @@
 	{
 		if (BoxType==SHORT_DOUBLE_BOX || BoxType==SHORT_SINGLE_BOX)
 		{
+			SetScreen(X1,Y1,X2,Y2,L' ',Colors[VMenuColorBody]);
+
 			Box(X1,Y1,X2,Y2,Colors[VMenuColorBox],BoxType);
 
 			if (!CheckFlags(VMENU_LISTBOX|VMENU_ALWAYSSCROLLBAR))
Index: dialog.cpp
===================================================================
--- dialog.cpp	(revision 6311)
+++ dialog.cpp	(working copy)
@@ -2267,6 +2267,8 @@
 		case MCODE_F_MENU_GETVALUE:
 		case MCODE_F_MENU_ITEMSTATUS:
 		case MCODE_V_MENU_VALUE:
+		case MCODE_F_MENU_FILTER:
+		case MCODE_F_MENU_FILTERSTR:
 		{
 			const wchar_t *str = (const wchar_t *)vParam;
 
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 6311)
+++ macro.cpp	(working copy)
@@ -408,6 +408,8 @@
 	{L"MENU.ITEMSTATUS",  1, 1,   MCODE_F_MENU_ITEMSTATUS,  nullptr, 0,nullptr,L"N=Menu.ItemStatus([N])",0,usersFunc},
 	{L"MENU.SELECT",      3, 2,   MCODE_F_MENU_SELECT,      nullptr, 0,nullptr,L"N=Menu.Select(S[,N[,Dir]])",0,usersFunc},
 	{L"MENU.SHOW",        6, 5,   MCODE_F_MENU_SHOW,        nullptr, 0,nullptr,L"S=Menu.Show(Items[,Title[,Flags[,FindOrFilter[,X[,Y]]]]])",IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT,menushowFunc},
+	{L"MENU.FILTER",      2, 2,   MCODE_F_MENU_FILTER,      nullptr, 0,nullptr,L"N=Menu.Filter([Action[,Mode]])",0,usersFunc},
+	{L"MENU.FILTERSTR",   2, 2,   MCODE_F_MENU_FILTERSTR,   nullptr, 0,nullptr,L"N=Menu.FilterStr([Action[,S]])",0,usersFunc},
 	{L"MIN",              2, 0,   MCODE_F_MIN,              nullptr, 0,nullptr,L"N=Min(N1,N2)",0,minFunc},
 	{L"MLOAD",            1, 0,   MCODE_F_MLOAD,            nullptr, 0,nullptr,L"N=MLoad(S)",0,mloadFunc},
 	{L"MMODE",            2, 1,   MCODE_F_MMODE,            nullptr, 0,nullptr,L"N=MMode(Action[,Value])",0,usersFunc},
@@ -5361,7 +5363,69 @@
 			VMStack.Push(Result);
 			goto begin;
 		}
+		case MCODE_F_MENU_FILTER:      // N=Menu.Filter([Action[,Mode]])
+		case MCODE_F_MENU_FILTERSTR:   // S=Menu.FilterStr([Action[,S]])
+		{
+			_KEYMACRO(CleverSysLog Clev(Key == MCODE_F_MENU_FILTER? L"MCODE_F_MENU_FILTER":L"MCODE_F_MENU_FILTERSTR"));
+			bool succees=false;
+			TVar tmpAction;
 
+			VMStack.Pop(tmpVar);
+			VMStack.Pop(tmpAction);
+			if (tmpAction.isUnknown())
+				tmpAction=Key == MCODE_F_MENU_FILTER ? 4 : 0;
+			
+			int CurMMode=CtrlObject->Macro.GetMode();
+
+			if (IsMenuArea(CurMMode) || CurMMode == MACRO_DIALOG)
+			{
+				Frame *f=FrameManager->GetCurrentFrame(), *fo=nullptr;
+
+				//f=f->GetTopModal();
+				while (f)
+				{
+					fo=f;
+					f=f->GetTopModal();
+				}
+
+				if (!f)
+					f=fo;
+
+				if (f)
+				{
+					if (Key == MCODE_F_MENU_FILTER)
+					{
+						if (tmpVar.isUnknown())
+							tmpVar = -1;
+						tmpVar=f->VMProcess(Key,(void*)static_cast<INT_PTR>(tmpVar.toInteger()),tmpAction.toInteger());
+						succees=true;
+					}
+					else
+					{
+						string NewStr;
+						if (tmpVar.isString())
+							NewStr = tmpVar.toString();
+						if (f->VMProcess(Key,(void*)&NewStr,tmpAction.toInteger()))
+						{
+							tmpVar=NewStr.CPtr();
+							succees=true;
+						}
+					}
+				}
+			}
+
+			if (!succees)
+			{
+				if (Key == MCODE_F_MENU_FILTER)
+					tmpVar = -1;
+				else
+					tmpVar = L"";
+			}
+
+			VMStack.Push(tmpVar);
+			goto begin;
+		}
+
 		default:
 		{
 			size_t J;
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 6311)
+++ macroopcode.hpp	(working copy)
@@ -173,6 +173,8 @@
 	MCODE_F_MENU_GETHOTKEY,           // S=gethotkey([N])
 	MCODE_F_MENU_SELECT,              // N=Menu.Select(S[,N[,Dir]])
 	MCODE_F_MENU_SHOW,                // S=Menu.Show(Items[,Title[,Flags[,FindOrFilter[,X[,Y]]]]])
+	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
+	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 	MCODE_F_MIN,                      // N=min(N1,N2)
 	MCODE_F_MOD,                      // N=mod(a,b) == a %  b
 	MCODE_F_MLOAD,                    // B=mload(var)
vmenu_macro.diff (14,488 bytes)   

Maximus

2011-06-05 21:39

reporter   bugnote:0007152

Last edited: 2011-06-05 21:39

Итого:

функция N=Menu.Filter([Action[,Mode])
Action
  0 - фильтр
    Mode
      -1 - (по умолчанию) вернуть 1 если фильтр уже включен, 0 - фильтр выключен
       1 - включить фильтр, если фильтр уже включен - ничего не делает
       0 - выключить фильтр
  1 - фиксация текста фильтра
    Mode
      -1 - (по умолчанию) вернуть 1 если текст фильтра зафиксирован, 0 - фильтр можно менять с клавиатуры
       1 - зафиксировать фильтр
       0 - отменить фиксацию фильтра
  2 - вернуть 1 если фильтр включен и строка фильтра не пуста
  3 - вернуть количество отфильтрованных (невидимых) строк\
  4 - (по умолчанию) подправить высоту списка под количество элементов
Если мы не в списке - возвращает -1,
если код возврата специально не оговорен, в случае успеха возвращает 1, в случае ошибки 0.

функция S=Menu.FilterStr([Action[,S])
Action
  0 - (по умолчанию) вернуть текущую строку, если фильтр включен
  1 - установить (заменить) в фильтре строку S.
      Если фильтр не был включен - включает его, режим фиксации не трогается, но игнорируется.
      Возвращает предыдущее значение строки фильтра.
В случае ошибки возвращает пустую строку

Maximus

2011-06-05 21:40

reporter   bugnote:0007153

Патч объединен с этим
http://bugs.farmanager.com/view.php?id=1788
т.к. много чего пересекается

Maximus

2011-06-05 22:05

reporter  

enc2.diff (3,179 bytes)   
Index: menus.html
===================================================================
--- menus.html	(revision 6311)
+++ menus.html	(working copy)
@@ -140,6 +140,56 @@
     </td>
   </tr>
   <tr>
+    <td>N=<dfn><a name="menu.filter">menu.filter</a></dfn>([Action[,Mode]])</td>
+    <td><p>������� ������� �������� (CtrlAltF).</p>
+       <table class="cont2 params lite tiny">
+        <col class="value">
+        <col>
+        <tr><th><var>Action</var></th><th>��������</th></tr>
+        <tr><td>0</td><td>������� ������
+           <table class="cont2 params lite tiny">
+            <col class="value">
+            <col>
+            <tr><th><var>Mode</var></th><th>��������</th></tr>
+            <tr><td>-1</td><td>(�� �������) ������ 1 ���� ����� ��� �����, 0 - ����� �����</td></tr>
+            <tr><td>&nbsp;0</td><td>����� �����, ���� ����� ��� ����� - ����� �� ������</td></tr>
+            <tr><td>&nbsp;1</td><td>����� �����</td></tr>
+           </table>
+        </td></tr>
+        <tr><td>1</td><td>������ ������ ������ (CtrlAltL)
+           <table class="cont2 params lite tiny">
+            <col class="value">
+            <col>
+            <tr><th><var>Mode</var></th><th>��������</th></tr>
+            <tr><td>-1</td><td>(�� �������) ������ 1 ���� ����� ������ ������������, 0 - ����� ����� ���� � ���������</td></tr>
+            <tr><td>&nbsp;0</td><td>������� ������ ������</td></tr>
+            <tr><td>&nbsp;1</td><td>������������ �����</td></tr>
+           </table>
+        </td></tr>
+        <tr><td>2</td><td>������ 1 ���� ����� ����� � ������ ������ �� �����</td></tr>
+        <tr><td>3</td><td>������ ��������� ������������ (�������) �����</td></tr>
+        <tr><td>3</td><td>(�� �������) ��������� ����� ������ ��� ��������� ���������</td></tr>
+       </table>
+       <p>���� ������� ���������� (�� ���; �� ������) ��������� -1.</p>
+       <p>���� ��� �������� �������� �� ��������, � ����� ����� ��������� 1, � ����� ����� 0.</p>
+    </td>
+  </tr>
+  <tr>
+    <td>S=<dfn><a name="menu.filterstr">menu.filterstr</a></dfn>([Action[,S]])</td>
+    <td><p>������� ������� �� ������� ������ (CtrlAltF).</p>
+       <table class="cont2 params lite tiny">
+        <col class="value">
+        <col>
+        <tr><th><var>Action</var></th><th>��������</th></tr>
+        <tr><td>0</td><td>(�� �������) ������ ����� ������, ���� ����� �����</td></tr>
+        <tr><td>1</td><td><p>��������� (�������) � ������ ������ <var>S</var></p>
+          <p>���� ����� �� �� ����� - ������ ���, ����� ������� �� ��������, �� �����������.</p>
+          <p>��������� �������� ������� ������ ������</p>
+        </td></tr>
+       </table>
+    </td>
+  </tr>
+  <tr>
     <td>S=<dfn><a name="menu.getvalue">menu.getvalue</a></dfn>([Pos])</td>
     <td><p>��������� ����� ������ ��� � ������� <var>Pos</var>.</p>
       <p>���� ������ "�����" �� ��� ��� ����� <var>Pos</var> �� ������� (���� 0 ��� ���� ��������� ������� � ���), �� ���������� ����� ������.</p>
enc2.diff (3,179 bytes)   

Maximus

2011-06-05 22:05

reporter   bugnote:0007154

+описание для писания

Maximus

2011-06-05 22:57

reporter   bugnote:0007155

PS. еще в патче поправлен следующий глюк: после редактирования макроса в "FAR Macro browser" отображался весь список макросов невзирая на включенный фильтр.

vskirdin

2011-06-10 09:14

administrator   bugnote:0007181

закончили? можно патчи применять?

Maximus

2011-06-10 09:32

reporter   bugnote:0007184

вроде все норм

vskirdin

2011-06-10 10:35

administrator   bugnote:0007188

build 2066

JohnDoe

2013-01-26 21:23

updater   bugnote:0010126

Last edited: 2013-01-26 21:26

В Писании (menu.filter) ошибка: Action=3 присутствует 2 раза (4 - отсутствует).

JohnDoe

2013-01-26 21:29

updater   bugnote:0010127

Для Mode предлагаю добавить значение =2 "Toggle", т.е. то же самое что нажатие соответствующей комбинации CtrlAltF (или CtrlAltL)

JohnDoe

2013-01-26 21:37

updater   bugnote:0010128

Предлагаю поменять значение по умолчанию для Action.
0 лучше, в этом случае вызов Menu.Filter() без параметров вернёт состояние фильтра (включен/выключен).
А для перерисовки надо будет явно задать Menu.Filter(4)

Имхо исходя из названия фунции всё-таки логичнее, если вызов без параметров не будет выполнять действий.

JohnDoe

2013-06-14 09:50

updater   bugnote:0011143

http://api.farmanager.com/ru/macro/macrocmd/prop_func/menus.html#menu.filter
Перепутаны описания действий для Menu.Filter(0,1) и Menu.Filter(0,0)

shmuel

2013-06-18 16:40

developer   bugnote:0011168

> Перепутаны описания действий для Menu.Filter(0,1) и Menu.Filter(0,0)

Поправил.

JohnDoe

2013-06-19 09:50

updater   bugnote:0011174

Там же: Action=3 присутствует 2 раза (4 - отсутствует).

shmuel

2013-06-19 10:51

developer   bugnote:0011175

> Там же: Action=3 присутствует 2 раза (4 - отсутствует).

Поправил. То, что 4 не работает, вас не смущает?

JohnDoe

2013-06-19 10:55

updater   bugnote:0011176

Last edited: 2013-06-19 10:56

Не приходилось пользоваться, странно даже что это действие выбрано по умолчанию.

Выше я предлагал изменить умолчание на 0 (раз 4 до сих пор не работало, значит изменение никому ничего не поломает)

shmuel

2013-06-19 11:08

developer   bugnote:0011177

Action==4 не работает, начиная с билда 2897 (только что проверил).

lort

2013-06-20 17:59

developer   bugnote:0011190

Action==4 в 3469 поправил

shmuel

2013-06-20 21:50

developer   bugnote:0011192

> Action==4 в 3469 поправил

Но появилась новая проблема: http://forum.farmanager.com/viewtopic.php?f=9&p=110977#p110977

JohnDoe

2014-01-22 10:10

updater   bugnote:0011727

Action==4
В момент подстройки (сужения) высоты списка явно видно мелькание меню.
Т.е. можно рассмотреть что меню полностью закрывается (мелькает текст под ним), и затем открывается новое меню.
Для наглядности привожу макрос, реализующий автоподстроку

Macro {
  area="Menu"; key="/./";
  condition=function() return Menu.Filter(0)==1 end;
  action=function()
    Keys "AKey"
    Menu.Filter(4)
  end;
}

Issue History

Date Modified Username Field Change
2011-06-02 07:35 Maximus New Issue
2011-06-02 09:49 Maximus Note Added: 0007117
2011-06-02 14:16 Maximus Note Edited: 0007117
2011-06-02 15:55 JohnDoe Note Added: 0007118
2011-06-02 15:56 JohnDoe Note Edited: 0007118
2011-06-02 15:57 JohnDoe Note Edited: 0007118
2011-06-02 18:53 Maximus Note Added: 0007120
2011-06-03 17:18 JohnDoe Note Added: 0007130
2011-06-03 17:42 JohnDoe Note Added: 0007131
2011-06-03 17:48 JohnDoe Note Edited: 0007130
2011-06-03 17:57 JohnDoe Note Edited: 0007130
2011-06-03 18:18 JohnDoe Note Edited: 0007131
2011-06-03 18:22 JohnDoe Note Edited: 0007131
2011-06-03 18:23 JohnDoe Note Edited: 0007130
2011-06-03 18:25 JohnDoe Note Edited: 0007130
2011-06-03 18:33 JohnDoe Note Edited: 0007130
2011-06-03 18:36 JohnDoe Note Edited: 0007131
2011-06-03 18:37 JohnDoe Note Edited: 0007131
2011-06-03 18:38 JohnDoe Note Edited: 0007130
2011-06-03 18:50 Maximus Note Added: 0007135
2011-06-03 18:51 JohnDoe Note Edited: 0007130
2011-06-03 18:53 JohnDoe Note Added: 0007136
2011-06-03 18:55 JohnDoe Note Edited: 0007136
2011-06-03 19:02 Maximus Note Added: 0007138
2011-06-03 19:19 JohnDoe Note Added: 0007139
2011-06-03 19:22 JohnDoe Note Edited: 0007139
2011-06-03 19:24 JohnDoe Note Edited: 0007139
2011-06-03 19:30 JohnDoe Note Edited: 0007139
2011-06-03 19:48 JohnDoe Note Added: 0007141
2011-06-03 19:57 JohnDoe Note Edited: 0007141
2011-06-04 00:24 JohnDoe Note Added: 0007142
2011-06-05 21:31 Maximus File Added: vmenu_macro.diff
2011-06-05 21:39 Maximus Note Added: 0007152
2011-06-05 21:39 Maximus Note Edited: 0007152
2011-06-05 21:40 Maximus Note Added: 0007153
2011-06-05 22:05 Maximus File Added: enc2.diff
2011-06-05 22:05 Maximus Note Added: 0007154
2011-06-05 22:57 Maximus Note Added: 0007155
2011-06-10 09:14 vskirdin Note Added: 0007181
2011-06-10 09:32 Maximus Note Added: 0007184
2011-06-10 10:12 vskirdin Assigned To => vskirdin
2011-06-10 10:12 vskirdin Status new => assigned
2011-06-10 10:35 vskirdin Note Added: 0007188
2011-06-10 10:35 vskirdin Status assigned => feedback
2013-01-26 21:23 JohnDoe Note Added: 0010126
2013-01-26 21:25 JohnDoe Note Edited: 0010126
2013-01-26 21:26 JohnDoe Note Edited: 0010126
2013-01-26 21:29 JohnDoe Note Added: 0010127
2013-01-26 21:37 JohnDoe Note Added: 0010128
2013-02-03 00:33 alexy Severity minor => feature
2013-06-14 09:50 JohnDoe Note Added: 0011143
2013-06-18 16:40 shmuel Note Added: 0011168
2013-06-19 09:50 JohnDoe Note Added: 0011174
2013-06-19 10:51 shmuel Note Added: 0011175
2013-06-19 10:55 JohnDoe Note Added: 0011176
2013-06-19 10:56 JohnDoe Note Edited: 0011176
2013-06-19 11:08 shmuel Note Added: 0011177
2013-06-20 17:59 lort Note Added: 0011190
2013-06-20 21:50 shmuel Note Added: 0011192
2014-01-22 10:10 JohnDoe Note Added: 0011727
2014-01-22 10:15 JohnDoe Status feedback => assigned