View Issue Details

IDProjectCategoryView StatusLast Update
0001788Wishes_Commonpublic2013-02-03 00:34
ReporterMaximus Assigned Tovskirdin  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status closedResolutionfixed 
Product Version3.0 
Summary0001788: Сделать удобным использование быстрого фильтра в списках (CtrlAltF)
DescriptionНадоело, в общем, патч.

Если при увеличении строки фильтра выделенная строка оказывается скрытой прыгаем
на первую видимую строку рядом с предыдущей (сверху или снизу - зависит от предыдущего
положения выделенной строки - в верхней или нижней части списка).

В фильтрации не участвует текст разделителей.
Если группа оказывается скрытой - разделитель перед ней тоже скрывается.

Автоматическое увеличение высоты списка при увеличении количества видимых строк
(сброс фильтра или уменьшение строки фильтра).
Сценарий (в панелях): ShiftF4 Tab CtrlDown CtrlAltF "650" Esc CtrlDown CtrlAltF
Ранее, несмотря на то что фильтра уже нет, высота списка оставалась всего 2 строки.

В довесок:
При нажатии Home в истории папок (например) первая дата (разделитель) оставалась невидимой.
TagsNo tags attached.
Build0

Relationships

related to 0001586 closedvskirdin Far Manager Проблема использования CtrlAltF в Выпадающем списке диалога 

Activities

Maximus

2011-06-01 21:10

reporter  

vmenu.110601.diff (5,633 bytes)   
Index: vmenu.cpp
===================================================================
--- vmenu.cpp	(revision 6305)
+++ vmenu.cpp	(working copy)
@@ -69,6 +69,7 @@
 	strTitle(Title),
 	SelectPos(-1),
 	TopPos(0),
+	WasAutoHeight(false),
 	MaxLength(0),
 	BoxType(DOUBLE_BOX),
 	ParentDialog(ParentDialog),
@@ -649,47 +650,147 @@
 
 	ItemHiddenCount=0;
 
+	FilterUpdateHeight();
+
 	if (SelectPos < 0)
 		SetSelectPos(0,1);
 }
 
 void VMenu::FilterStringUpdated(bool bLonger)
 {
+	int PrevSeparator = -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++;
+					}
+					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
+				{
+					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 (PrevSeparator != -1)
+					{
+						// ���������� ����� ����� ������ ������� �� ����
+						Item[PrevSeparator]->Flags &= ~LIF_HIDDEN;
+						ItemHiddenCount--;
+						PrevSeparator = -1;
+					}
+				}
 			}
+			else if ((PrevSeparator != -1) && (Item[i]->Flags & LIF_SEPARATOR))
+			{
+				PrevSeparator = -1;
+			}
 		}
+
+		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()
+{
+	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)
+		{
+			SetPosition(X1,Y1,X2,NewY2);
+		}
+	}
+}
+
 bool VMenu::IsFilterEditKey(int Key)
 {
 	return (Key>=(int)KEY_SPACE && Key<0xffff) || Key==KEY_BS;
@@ -1027,7 +1128,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,12 +1703,18 @@
 			}
 		}
 
+		WasAutoHeight = false;
 		if (Y2 <= 0)
 		{
 			if (MaxHeight && MaxHeight<GetShowItemCount())
+			{
 				Y2 = Y1 + MaxHeight + 1;
+			}
 			else
+			{
 				Y2 = Y1 + GetShowItemCount() + 1;
+				WasAutoHeight = true;
+			}
 		}
 
 		if (Y2 > ScrY)
Index: vmenu.hpp
===================================================================
--- vmenu.hpp	(revision 6305)
+++ vmenu.hpp	(working copy)
@@ -210,6 +210,7 @@
 		int SelectPos;
 		int TopPos;
 		int MaxHeight;
+		bool WasAutoHeight;
 		int MaxLength;
 		int BoxType;
 		bool PrevCursorVisible;
@@ -324,6 +325,7 @@
 		int  FindItem(int StartIndex,const wchar_t *Pattern,UINT64 Flags=0);
 		void RestoreFilteredItems();
 		void FilterStringUpdated(bool bLonger);
+		void FilterUpdateHeight();
 		void SetFilterEnabled(bool bEnabled) { bFilterEnabled=bEnabled; };
 		void SetFilterLocked(bool bLocked) { bFilterEnabled=bLocked; };
  		bool AddToFilter(const wchar_t *str);
vmenu.110601.diff (5,633 bytes)   

Maximus

2011-06-05 20:33

reporter   bugnote:0007151

Обновленный патч выложен здесь:
http://bugs.farmanager.com/view.php?id=1789

vskirdin

2011-06-10 08:15

administrator   bugnote:0007182

если в 0001789 ЭТО сделано, то разумнее этот Инц закрыть.
не?

Maximus

2011-06-10 08:31

reporter   bugnote:0007183

закрывай

vskirdin

2011-06-10 09:10

administrator   bugnote:0007186

закрыт в пользу 0001789

Issue History

Date Modified Username Field Change
2011-06-01 21:10 Maximus New Issue
2011-06-01 21:10 Maximus File Added: vmenu.110601.diff
2011-06-05 19:33 alexy Relationship added related to 0001586
2011-06-05 20:33 Maximus Note Added: 0007151
2011-06-10 08:15 vskirdin Note Added: 0007182
2011-06-10 08:31 Maximus Note Added: 0007183
2011-06-10 09:10 vskirdin Build => 0
2011-06-10 09:10 vskirdin Note Added: 0007186
2011-06-10 09:10 vskirdin Status new => closed
2011-06-10 09:10 vskirdin Assigned To => vskirdin
2011-06-10 09:10 vskirdin Resolution open => fixed
2013-02-03 00:34 alexy Severity minor => feature