View Issue Details

IDProjectCategoryView StatusLast Update
0001221WishesFiles Highlightingpublic2013-02-03 00:33
Reporteruser379Assigned ToDrKnS  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Platformx64OSWindowsOS VersionVista SP2
Product Version2.0 
Fixed in Version3.0 
Summary0001221: Раскраска hard link в панели
DescriptionЕсть необходимость раскрашивать файлы, у которых число жестких связей больше одного, т.е. которые имеют hard link. Лучше с указанием порога, после пересечения которого нужно отмечать файлы цветом, т.к. может быть необходимо искать на диске файлы с множественными "дублями", причём порог субъективен.
Steps To ReproduceНажимаем LCtrl+9 и видем в крайней колонке число связей для файла.
При достижении числа связей двух и более (или по другому пороговому критерию) есть необходимость установить фильтр для Files highlighting, но на одноименной панели нет атрибута "has hard links" или поля для включения порога, после достижения которого файл будет отмечаться цветом.
Additional InformationВообще-то тема навеяна случаями нечаянного удаления файлов, когда в папке, являющейся symbolic link, обнаруживаются файлы, идентичные файлам в исходной папке. Тоже надо бы поправить, дав возможность отличать файлы в папке-ссылке (которые тоже в свою очередь ссылки) от истинных файлов, ибо удаление в этой папке приводит к удалению в папке истинной. Может цвет пути в заголовке панели тоже заодно изменять, когда текущее местоположение внутри папки?
Tagshard link
Build2283

Relationships

duplicate of 0000084 closedalexy Атрибут для раскраски файлов - "Более 1 жёсткой связи с файлом" 

Activities

samlyukov

2011-09-10 10:45

reporter   bugnote:0007648

почему-то не закрыт.

Sergey Karpukhin

2011-12-01 12:32

reporter  

hardlink_filter_patch.diff (8,712 bytes)   
Index: farlang.templ.m4
===================================================================
--- farlang.templ.m4	(revision 6904)
+++ farlang.templ.m4	(working copy)
@@ -19603,6 +19603,15 @@
 "<="
 "<="
 
+MFileHardLinksCount
+"Болee одной жёсткой ссылки"
+"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+
 MFileFilterDate
 "&Дата/Время:"
 "Da&te/Time:"
Index: filefilterparams.cpp
===================================================================
--- filefilterparams.cpp	(revision 6904)
+++ filefilterparams.cpp	(working copy)
@@ -51,11 +51,13 @@
 #include "strmix.hpp"
 #include "mix.hpp"
 #include "console.hpp"
+#include "flink.hpp"
 
 FileFilterParams::FileFilterParams()
 {
 	SetMask(1,L"*");
 	SetSize(0,L"",L"");
+	SetHardLinks(0,0,0);
 	ClearStruct(FDate);
 	ClearStruct(FAttr);
 	ClearStruct(FHighlight.Colors);
@@ -207,6 +209,13 @@
 	FSize.SizeBelowReal=ConvertFileSizeString(FSize.SizeBelow);
 }
 
+void FileFilterParams::SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow)
+{
+	FHardLinks.Used=Used;
+	FHardLinks.CountAbove=HardLinksAbove;
+	FHardLinks.CountBelow=HardLinksBelow;
+}
+
 void FileFilterParams::SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear)
 {
 	FAttr.Used=Used;
@@ -266,6 +275,16 @@
 	return FSize.Used;
 }
 
+bool FileFilterParams::GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const
+{
+	if (HardLinksAbove)
+		*HardLinksAbove = FHardLinks.CountAbove;
+	if (HardLinksBelow)
+		*HardLinksBelow = FHardLinks.CountBelow;
+	return FHardLinks.Used;
+}
+
+
 bool FileFilterParams::GetAttr(DWORD *AttrSet, DWORD *AttrClear) const
 {
 	if (AttrSet)
@@ -332,6 +351,15 @@
 		}
 	}
 
+	// ����� �������� ��������� ������ ����� �� ���� �����?
+	// ���� ���, ��� �������� �������, ����������� ��������� ��� ����� "����� ���� ��� ����"
+	if (FHardLinks.Used)
+	{
+		//if (GetNumberOfLinks(fde.strFileName)<FHardLinks.CountBelow)
+		if (GetNumberOfLinks(fde.strFileName)==1) 
+			return false;
+	}
+
 	// ����� �������� ������� ����� �����?
 	if (FDate.Used)
 	{
@@ -429,16 +457,16 @@
 		FILE_ATTRIBUTE_OFFLINE,
 		FILE_ATTRIBUTE_VIRTUAL,
 	};
-	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-4.4s %c %s";
 	const wchar_t DownArrow=0x2193;
 	const wchar_t *Name, *Mask;
 	wchar_t MarkChar[]=L"\" \"";
 	DWORD IncludeAttr, ExcludeAttr;
-	bool UseMask, UseSize, UseDate, RelativeDate;
+	bool UseMask, UseSize, UseHardLinks, UseDate, RelativeDate;
 
 	if (bPanelType)
 	{
@@ -447,7 +475,7 @@
 		Mask=FMask;
 		IncludeAttr=0;
 		ExcludeAttr=FILE_ATTRIBUTE_DIRECTORY;
-		RelativeDate=UseDate=UseSize=false;
+		RelativeDate=UseDate=UseSize=UseHardLinks=false;
 	}
 	else
 	{
@@ -464,6 +492,7 @@
 
 		UseSize=FF->GetSize(nullptr,nullptr);
 		UseDate=FF->GetDate(nullptr,nullptr,nullptr,&RelativeDate);
+		UseHardLinks=FF->GetHardLinks(nullptr,nullptr);
 	}
 
 	wchar_t Attr[ARRAYSIZE(AttrC)*2] = {};
@@ -481,7 +510,7 @@
 			*Ptr=*(Ptr+1)=L'.';
 	}
 
-	wchar_t SizeDate[4] = L"...";
+	wchar_t SizeDate[5] = L"....";
 
 	if (UseSize)
 	{
@@ -496,16 +525,21 @@
 			SizeDate[1]=L'D';
 	}
 
+	if (UseHardLinks)
+	{
+		SizeDate[2]=L'H';
+	}
+
 	if (bHighlightType)
 	{
 		if (FF->GetContinueProcessing())
-			SizeDate[2]=DownArrow;
+			SizeDate[3]=DownArrow;
 
 		strDest.Format(Format2, MarkChar, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], UseMask ? Mask : L"");
 	}
 	else
 	{
-		SizeDate[2]=0;
+		SizeDate[3]=0;
 
 		if (!Hotkey && !bPanelType)
 		{
@@ -594,6 +628,10 @@
 
 	ID_FF_SEPARATOR5,
 
+	ID_FF_HARDLINKS,
+
+	ID_FF_SEPARATOR6,
+
 	ID_FF_OK,
 	ID_FF_RESET,
 	ID_FF_CANCEL,
@@ -895,7 +933,7 @@
 	strTimeMask.Format(L"99%c99%c99%c999",TimeSeparator,TimeSeparator,DecimalSeparator);
 	FarDialogItem FilterDlgData[]=
 	{
-		{DI_DOUBLEBOX,3,1,76,18,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
+		{DI_DOUBLEBOX,3,1,76,20,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
 
 		{DI_TEXT,5,2,0,2,0,nullptr,nullptr,DIF_FOCUS,MSG(MFileFilterName)},
 		{DI_EDIT,5,2,74,2,0,FilterNameHistoryName,nullptr,DIF_HISTORY,L""},
@@ -966,10 +1004,13 @@
 
 		{DI_TEXT,0,16,0,16,0,nullptr,nullptr,DIF_SEPARATOR,L""},
 
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
+		{DI_CHECKBOX,5,17,0,17,0,nullptr,nullptr,0,MSG(MFileHardLinksCount)},//�������� ���� ������� � �����
+		{DI_TEXT,0,18,0,18,0,nullptr,nullptr,DIF_SEPARATOR,L""},// � ����������
+
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
 	};
 	FilterDlgData[0].Data=MSG(ColorConfig?MFileHilightTitle:MFileFilterTitle);
 	MakeDialogItemsEx(FilterDlgData,FilterDlg);
@@ -1032,6 +1073,7 @@
 	FilterDlg[ID_FF_MATCHSIZE].Selected=FF->GetSize(&SizeAbove,&SizeBelow)?1:0;
 	FilterDlg[ID_FF_SIZEFROMEDIT].strData=SizeAbove;
 	FilterDlg[ID_FF_SIZETOEDIT].strData=SizeBelow;
+	FilterDlg[ID_FF_HARDLINKS].Selected=FF->GetHardLinks(nullptr,nullptr)?1:0; //���� ��� � ������� ����� ���� ����������� ������� ������
 
 	if (!FilterDlg[ID_FF_MATCHSIZE].Selected)
 		for (int i=ID_FF_SIZEFROMSIGN; i <= ID_FF_SIZETOEDIT; i++)
@@ -1151,6 +1193,7 @@
 			FF->SetSize(FilterDlg[ID_FF_MATCHSIZE].Selected!=0,
 			            FilterDlg[ID_FF_SIZEFROMEDIT].strData,
 			            FilterDlg[ID_FF_SIZETOEDIT].strData);
+			FF->SetHardLinks(FilterDlg[ID_FF_HARDLINKS].Selected!=0,0,0); //���� ������������� ����� ���� ����������� ��������
 			bRelative = FilterDlg[ID_FF_DATERELATIVE].Selected!=0;
 
 			LPWSTR TimeBefore = FilterDlg[ID_FF_TIMEBEFOREEDIT].strData.GetBuffer();
Index: filefilterparams.hpp
===================================================================
--- filefilterparams.hpp	(revision 6904)
+++ filefilterparams.hpp	(working copy)
@@ -105,6 +105,13 @@
 			bool Used;
 		} FSize;
 
+		struct // ���� ��������� � ������, ���� ����� ��������� ������ �����. ���� ��� ������ ��������� ����� ���� Used
+		{
+			bool Used;
+			unsigned __int64 CountAbove; //��� ��� ������ ��� wchar_t � ������������� � ����� �� ������������? 
+			unsigned __int64 CountBelow; 
+		} FHardLinks;
+
 		struct
 		{
 			bool Used;
@@ -131,6 +138,7 @@
 		void SetMask(bool Used, const wchar_t *Mask);
 		void SetDate(bool Used, DWORD DateType, FILETIME DateAfter, FILETIME DateBefore, bool bRelative);
 		void SetSize(bool Used, const wchar_t *SizeAbove, const wchar_t *SizeBelow);
+		void SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow);
 		void SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear);
 		void SetColors(HighlightDataColor *Colors);
 		void SetSortGroup(int SortGroup) { FHighlight.SortGroup = SortGroup; }
@@ -142,6 +150,7 @@
 		bool  GetMask(const wchar_t **Mask) const;
 		bool  GetDate(DWORD *DateType, FILETIME *DateAfter, FILETIME *DateBefore, bool *bRelative) const;
 		bool  GetSize(const wchar_t **SizeAbove, const wchar_t **SizeBelow) const;
+		bool  GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const;
 		bool  GetAttr(DWORD *AttrSet, DWORD *AttrClear) const;
 		void  GetColors(HighlightDataColor *Colors) const;
 		int   GetMarkChar() const;
hardlink_filter_patch.diff (8,712 bytes)   

Sergey Karpukhin

2011-12-01 12:50

reporter   bugnote:0008021

К сожалению я подоспел уже, похоже, к шапочным разборкам: главный тикет по теме (0000084) давно закрыли с резолюцией "нэ будет"

Но может быть все таки стоит попробовать внедрить требуемую функциональность?

Я загрузил патч (hardlink_filter_patch.diff) с реализацией необходимого, для последней версии с транка (rev 6904, по справке - Far 3.0 build 2273).

Патч вводит дополнительное условие для фильтров в поиске и подсветке "файл имеет больше одного хардлинка". я думаю этого хватит в 95% случаев, но можно при желании раскрутить условия и дальше, на манер "больше 5 но меньше 10 хардлинков"

Согласен, накладные расходы на вызовы GetNumberOfLinks будут, но пока новая опция в фильтре выключена, то никаких дополнительных затрат мы не имеет. А если же пользователя прижмет, и ему, кровь из носу, необходимо будет подсветить нужные файлы в панели или забабахать хитрый фильтр для поиска, то тут уж можно будет смириться с накладными расходами, ибо цель оправдывает средства :-)

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

Sergey Karpukhin

2011-12-01 12:55

reporter   bugnote:0008022

Last edited: 2011-12-01 12:56

Сделал патч для подсветки и поиска файлов по дополнительному условию "Файл имеет больше одного хардлинка"

C удовольствием допилю патч если всплывут косяки или недоделки. Хочу чтобы данная функциональность все же появилось в новой версии FARa

DrKnS

2011-12-01 13:14

administrator   bugnote:0008023

> Сделал патч для подсветки и поиска файлов по дополнительному условию "Файл имеет больше одного хардлинка"

Это прекрасно, но где сохранение и загрузка?

Sergey Karpukhin

2011-12-01 13:25

reporter   bugnote:0008024

> Это прекрасно, но где сохранение и загрузка?

Можно, пожалуйста, уточнить о каком сохранении и загрузке идет речь?

Имеется ввиду сохранения новых фильтров при сохранении всех настроек по Shift+F9, или что-то еще?

DrKnS

2011-12-01 13:30

administrator   bugnote:0008025

hilight.cpp: LoadFilter/SaveFilter

filefilter.cpp: FileFilter::InitFilter(), FileFilter::SaveFilters()

Sergey Karpukhin

2011-12-01 13:34

reporter   bugnote:0008026

ок, буду ковыряться дальше.

возникающие, по ходу, вопросы задавать тут?

DrKnS

2011-12-01 13:36

administrator   bugnote:0008027

Да.

Sergey Karpukhin

2011-12-02 03:00

reporter  

hardlink_filter_patch_v2.diff (11,962 bytes)   
Index: farlang.templ.m4
===================================================================
--- farlang.templ.m4	(revision 6904)
+++ farlang.templ.m4	(working copy)
@@ -19603,6 +19603,15 @@
 "<="
 "<="
 
+MFileHardLinksCount
+"Болee одной жёсткой ссылки"
+"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+
 MFileFilterDate
 "&Дата/Время:"
 "Da&te/Time:"
Index: filefilter.cpp
===================================================================
--- filefilter.cpp	(revision 6904)
+++ filefilter.cpp	(working copy)
@@ -852,6 +852,14 @@
 			cfg->GetValue(key,L"UseSize",&UseSize);
 			NewFilter->SetSize(UseSize!=0, strSizeAbove, strSizeBelow);
 
+			unsigned __int64 UseHardLinks = 0;
+			cfg->GetValue(key,L"UseHardLinks",&UseHardLinks);
+			unsigned __int64 HardLinksAbove;
+			cfg->GetValue(key,L"HardLinksAbove",&HardLinksAbove);
+			unsigned __int64 HardLinksBelow;
+			cfg->GetValue(key,L"HardLinksAbove",&HardLinksBelow);
+			NewFilter->SetHardLinks(UseHardLinks!=0,HardLinksAbove,HardLinksBelow);
+
 			unsigned __int64 UseAttr = 1;
 			cfg->GetValue(key,L"UseAttr",&UseAttr);
 			unsigned __int64 AttrSet = 0;
@@ -948,6 +956,10 @@
 		cfg->SetValue(key,L"UseSize",CurFilterData->GetSize(&SizeAbove, &SizeBelow)?1:0);
 		cfg->SetValue(key,L"SizeAboveS",SizeAbove);
 		cfg->SetValue(key,L"SizeBelowS",SizeBelow);
+		unsigned __int64 HardLinksAbove,HardLinksBelow;
+		cfg->SetValue(key,L"UseHardLinks",CurFilterData->GetHardLinks(&HardLinksAbove,&HardLinksBelow)?1:0);
+		cfg->SetValue(key,L"HardLinksAboveS",SizeAbove);
+		cfg->SetValue(key,L"HardLinksBelowS",SizeBelow);
 		DWORD AttrSet, AttrClear;
 		cfg->SetValue(key,L"UseAttr",CurFilterData->GetAttr(&AttrSet, &AttrClear)?1:0);
 		cfg->SetValue(key,L"AttrSet",AttrSet);
Index: filefilterparams.cpp
===================================================================
--- filefilterparams.cpp	(revision 6904)
+++ filefilterparams.cpp	(working copy)
@@ -51,11 +51,13 @@
 #include "strmix.hpp"
 #include "mix.hpp"
 #include "console.hpp"
+#include "flink.hpp"
 
 FileFilterParams::FileFilterParams()
 {
 	SetMask(1,L"*");
 	SetSize(0,L"",L"");
+	SetHardLinks(0,0,0);
 	ClearStruct(FDate);
 	ClearStruct(FAttr);
 	ClearStruct(FHighlight.Colors);
@@ -207,6 +209,13 @@
 	FSize.SizeBelowReal=ConvertFileSizeString(FSize.SizeBelow);
 }
 
+void FileFilterParams::SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow)
+{
+	FHardLinks.Used=Used;
+	FHardLinks.CountAbove=HardLinksAbove;
+	FHardLinks.CountBelow=HardLinksBelow;
+}
+
 void FileFilterParams::SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear)
 {
 	FAttr.Used=Used;
@@ -266,6 +275,16 @@
 	return FSize.Used;
 }
 
+bool FileFilterParams::GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const
+{
+	if (HardLinksAbove)
+		*HardLinksAbove = FHardLinks.CountAbove;
+	if (HardLinksBelow)
+		*HardLinksBelow = FHardLinks.CountBelow;
+	return FHardLinks.Used;
+}
+
+
 bool FileFilterParams::GetAttr(DWORD *AttrSet, DWORD *AttrClear) const
 {
 	if (AttrSet)
@@ -332,6 +351,15 @@
 		}
 	}
 
+	// ����� �������� ��������� ������ ����� �� ���� �����?
+	// ���� ���, ��� �������� �������, ����������� ��������� ��� ����� "����� ���� ��� ����"
+	if (FHardLinks.Used)
+	{
+		//if (GetNumberOfLinks(fde.strFileName)<FHardLinks.CountBelow)
+		if (GetNumberOfLinks(fde.strFileName)==1) 
+			return false;
+	}
+
 	// ����� �������� ������� ����� �����?
 	if (FDate.Used)
 	{
@@ -429,16 +457,16 @@
 		FILE_ATTRIBUTE_OFFLINE,
 		FILE_ATTRIBUTE_VIRTUAL,
 	};
-	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-4.4s %c %s";
 	const wchar_t DownArrow=0x2193;
 	const wchar_t *Name, *Mask;
 	wchar_t MarkChar[]=L"\" \"";
 	DWORD IncludeAttr, ExcludeAttr;
-	bool UseMask, UseSize, UseDate, RelativeDate;
+	bool UseMask, UseSize, UseHardLinks, UseDate, RelativeDate;
 
 	if (bPanelType)
 	{
@@ -447,7 +475,7 @@
 		Mask=FMask;
 		IncludeAttr=0;
 		ExcludeAttr=FILE_ATTRIBUTE_DIRECTORY;
-		RelativeDate=UseDate=UseSize=false;
+		RelativeDate=UseDate=UseSize=UseHardLinks=false;
 	}
 	else
 	{
@@ -464,6 +492,7 @@
 
 		UseSize=FF->GetSize(nullptr,nullptr);
 		UseDate=FF->GetDate(nullptr,nullptr,nullptr,&RelativeDate);
+		UseHardLinks=FF->GetHardLinks(nullptr,nullptr);
 	}
 
 	wchar_t Attr[ARRAYSIZE(AttrC)*2] = {};
@@ -481,7 +510,7 @@
 			*Ptr=*(Ptr+1)=L'.';
 	}
 
-	wchar_t SizeDate[4] = L"...";
+	wchar_t SizeDate[5] = L"....";
 
 	if (UseSize)
 	{
@@ -496,16 +525,21 @@
 			SizeDate[1]=L'D';
 	}
 
+	if (UseHardLinks)
+	{
+		SizeDate[2]=L'H';
+	}
+
 	if (bHighlightType)
 	{
 		if (FF->GetContinueProcessing())
-			SizeDate[2]=DownArrow;
+			SizeDate[3]=DownArrow;
 
 		strDest.Format(Format2, MarkChar, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], UseMask ? Mask : L"");
 	}
 	else
 	{
-		SizeDate[2]=0;
+		SizeDate[3]=0;
 
 		if (!Hotkey && !bPanelType)
 		{
@@ -594,6 +628,10 @@
 
 	ID_FF_SEPARATOR5,
 
+	ID_FF_HARDLINKS,
+
+	ID_FF_SEPARATOR6,
+
 	ID_FF_OK,
 	ID_FF_RESET,
 	ID_FF_CANCEL,
@@ -895,7 +933,7 @@
 	strTimeMask.Format(L"99%c99%c99%c999",TimeSeparator,TimeSeparator,DecimalSeparator);
 	FarDialogItem FilterDlgData[]=
 	{
-		{DI_DOUBLEBOX,3,1,76,18,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
+		{DI_DOUBLEBOX,3,1,76,20,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
 
 		{DI_TEXT,5,2,0,2,0,nullptr,nullptr,DIF_FOCUS,MSG(MFileFilterName)},
 		{DI_EDIT,5,2,74,2,0,FilterNameHistoryName,nullptr,DIF_HISTORY,L""},
@@ -966,10 +1004,13 @@
 
 		{DI_TEXT,0,16,0,16,0,nullptr,nullptr,DIF_SEPARATOR,L""},
 
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
+		{DI_CHECKBOX,5,17,0,17,0,nullptr,nullptr,0,MSG(MFileHardLinksCount)},//�������� ���� ������� � �����
+		{DI_TEXT,0,18,0,18,0,nullptr,nullptr,DIF_SEPARATOR,L""},// � ����������
+
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
 	};
 	FilterDlgData[0].Data=MSG(ColorConfig?MFileHilightTitle:MFileFilterTitle);
 	MakeDialogItemsEx(FilterDlgData,FilterDlg);
@@ -1032,6 +1073,7 @@
 	FilterDlg[ID_FF_MATCHSIZE].Selected=FF->GetSize(&SizeAbove,&SizeBelow)?1:0;
 	FilterDlg[ID_FF_SIZEFROMEDIT].strData=SizeAbove;
 	FilterDlg[ID_FF_SIZETOEDIT].strData=SizeBelow;
+	FilterDlg[ID_FF_HARDLINKS].Selected=FF->GetHardLinks(nullptr,nullptr)?1:0; //���� ��� � ������� ����� ���� ����������� ������� ������
 
 	if (!FilterDlg[ID_FF_MATCHSIZE].Selected)
 		for (int i=ID_FF_SIZEFROMSIGN; i <= ID_FF_SIZETOEDIT; i++)
@@ -1151,6 +1193,7 @@
 			FF->SetSize(FilterDlg[ID_FF_MATCHSIZE].Selected!=0,
 			            FilterDlg[ID_FF_SIZEFROMEDIT].strData,
 			            FilterDlg[ID_FF_SIZETOEDIT].strData);
+			FF->SetHardLinks(FilterDlg[ID_FF_HARDLINKS].Selected!=0,0,0); //���� ������������� ����� ���� ����������� ��������
 			bRelative = FilterDlg[ID_FF_DATERELATIVE].Selected!=0;
 
 			LPWSTR TimeBefore = FilterDlg[ID_FF_TIMEBEFOREEDIT].strData.GetBuffer();
Index: filefilterparams.hpp
===================================================================
--- filefilterparams.hpp	(revision 6904)
+++ filefilterparams.hpp	(working copy)
@@ -105,6 +105,13 @@
 			bool Used;
 		} FSize;
 
+		struct // ���� ��������� � ������, ���� ����� ��������� ������ �����. ���� ��� ������ ��������� ����� ���� Used
+		{
+			bool Used;
+			unsigned __int64 CountAbove; //��� ��� ������ ��� wchar_t � ������������� � ����� �� ������������? 
+			unsigned __int64 CountBelow; 
+		} FHardLinks;
+
 		struct
 		{
 			bool Used;
@@ -131,6 +138,7 @@
 		void SetMask(bool Used, const wchar_t *Mask);
 		void SetDate(bool Used, DWORD DateType, FILETIME DateAfter, FILETIME DateBefore, bool bRelative);
 		void SetSize(bool Used, const wchar_t *SizeAbove, const wchar_t *SizeBelow);
+		void SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow);
 		void SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear);
 		void SetColors(HighlightDataColor *Colors);
 		void SetSortGroup(int SortGroup) { FHighlight.SortGroup = SortGroup; }
@@ -142,6 +150,7 @@
 		bool  GetMask(const wchar_t **Mask) const;
 		bool  GetDate(DWORD *DateType, FILETIME *DateAfter, FILETIME *DateBefore, bool *bRelative) const;
 		bool  GetSize(const wchar_t **SizeAbove, const wchar_t **SizeBelow) const;
+		bool  GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const;
 		bool  GetAttr(DWORD *AttrSet, DWORD *AttrClear) const;
 		void  GetColors(HighlightDataColor *Colors) const;
 		int   GetMarkChar() const;
Index: hilight.cpp
===================================================================
--- hilight.cpp	(revision 6904)
+++ hilight.cpp	(working copy)
@@ -71,6 +71,7 @@
 	*ContinueProcessing,
 	*UseDate,*DateType,*DateAfter,*DateBefore,*DateRelative,
 	*UseSize,*SizeAbove,*SizeBelow,
+	*UseHardLinks,*HardLinksAbove,*HardLinksBelow,
 	*HighlightEdit,*HighlightList;
 };
 
@@ -92,6 +93,7 @@
 	L"ContinueProcessing",
 	L"UseDate",L"DateType",L"DateAfter",L"DateBefore",L"DateRelative",
 	L"UseSize",L"SizeAboveS",L"SizeBelowS",
+	L"UseHardLinks",L"HardLinksAbove",L"HardLinksBelow",
 	L"HighlightEdit",L"HighlightList"
 };
 
@@ -238,6 +240,14 @@
 	cfg->GetValue(key,HLS.UseSize,&UseSize);
 	HData->SetSize(UseSize!=0, strSizeAbove, strSizeBelow);
 
+	unsigned __int64 UseHardLinks = 0;
+	unsigned __int64 HardLinksAbove = 0;
+	unsigned __int64 HardLinksBelow = 0;
+	cfg->GetValue(key,HLS.UseHardLinks,&UseHardLinks);
+	cfg->GetValue(key,HLS.HardLinksAbove,&HardLinksAbove);
+	cfg->GetValue(key,HLS.HardLinksBelow,&HardLinksBelow);
+	HData->SetHardLinks(UseHardLinks!=0,HardLinksAbove,HardLinksBelow);
+
 	if (bSortGroup)
 	{
 		unsigned __int64 UseAttr = 1;
@@ -881,6 +891,10 @@
 	cfg->SetValue(key,HLS.UseSize,CurHiData->GetSize(&SizeAbove, &SizeBelow)?1:0);
 	cfg->SetValue(key,HLS.SizeAbove,SizeAbove);
 	cfg->SetValue(key,HLS.SizeBelow,SizeBelow);
+	unsigned __int64 HardLinksAbove, HardLinksBelow;
+	cfg->SetValue(key,HLS.UseHardLinks,CurHiData->GetHardLinks(&HardLinksAbove, &HardLinksBelow)?1:0);
+	cfg->SetValue(key,HLS.HardLinksAbove,HardLinksAbove);
+	cfg->SetValue(key,HLS.HardLinksBelow,HardLinksBelow);
 	DWORD AttrSet, AttrClear;
 	cfg->SetValue(key,HLS.UseAttr,CurHiData->GetAttr(&AttrSet, &AttrClear)?1:0);
 	cfg->SetValue(key,(bSortGroup?HLS.AttrSet:HLS.IncludeAttributes),AttrSet);
hardlink_filter_patch_v2.diff (11,962 bytes)   

Sergey Karpukhin

2011-12-02 03:17

reporter   bugnote:0008029

hardlink_filter_patch_v2.diff

Исправил косяки по сохранению и загрузке.

Подсветка в панели работает адекватно. Для себя нашел удобным следующий режим: в списке фильтров для подсветки, у всех фильтров для файлов оставляю пустой "Marking Character" ставлю галку "Transparent" возле него, и включаю "Continue Processing". А потом в конце списка фильтров добавляю фильтр с Marking Character="*" белого цвета, для выделения файлов с множественными ссылками. Белый цвет звездочки позволяет различать файлы со ссылками от файлов имя которых начинается со звездочки.

Остались проблемы с поиском по новому фильтру - поиск корректно работает только в текущей папке. GetNumberOfLinks() подразумевает работу только по именам файлов, в текущем каталоге, а при поиске текущий каталог не меняется.

Есть ли возможность как-то малой кровью решить эту проблему? Можно конечно расковырять findfile.cpp, чтобы при поиске с включенной новой опцией в фильтре текущий каталог менялся, но выглядит это каким-то грязным хаком.

Еще есть вопрос по поводу перевода строк в числа. Если модернизировать опцию в фильтре, чтобы можно было задавать минимальное-максимальное количество ссылок, то каким способом лучше делать преобразование. Есть функции для перевода размера файлов из строк в числа - использовать их? или есть лучшие варианты?

DrKnS

2011-12-02 06:53

administrator   bugnote:0008031

> GetNumberOfLinks() подразумевает работу только по именам файлов, в текущем каталоге

Почему вы решили, что туда нельзя передавать полное имя?

> есть лучшие варианты?

wcstol/wcstoul, но вообще я не уверен, что фильтр вида "больше 5 но меньше 10 хардлинков" будет востребован.

Sergey Karpukhin

2011-12-02 08:28

reporter   bugnote:0008033

>> GetNumberOfLinks() подразумевает работу только по именам файлов, в текущем каталоге

>Почему вы решили, что туда нельзя передавать полное имя

Я немного неправильно выразился. Дело не в том, что функция не может обработать полное имя файла с путями, дело в том, что в функцию FileFilterParams::FileInFilter(), где мы проверяем все условия по фильтру (и вызываем обсуждаемый нами GetNumberOfLinks()), не приходит полное имя файла с путями. А если пришло только имя файла, то GetNumberOfLinks() считает что имя дано относительно текущей папки.

Через структуру FAR_FIND_DATA_EX передается только имя файла без путей. Эту структуру корежит явно не следует, поскольку она является частью PluginAPI, Нужен какой-нибудь "обходной путь" что-бы передать имя файла и полный путь в функцию FileFilterParams::FileInFilter()

DrKnS

2011-12-02 09:25

administrator   bugnote:0008034

> Эту структуру корежит явно не следует, поскольку она является частью PluginAPI

Она не является частью Plugin API.

Нужен какой-нибудь "обходной путь" что-бы передать имя файла и полный путь в
функцию FileFilterParams::FileInFilter()

Ну добавьте туда необязательный параметр const string* strFullName = nullptr, в чем проблема.

Sergey Karpukhin

2011-12-03 10:46

reporter  

hardlink_filter_patch_v3.diff (25,743 bytes)   
Index: copy.cpp
===================================================================
--- copy.cpp	(revision 6911)
+++ copy.cpp	(working copy)
@@ -1148,7 +1148,7 @@
 	{
 		if (UseFilter)
 		{
-			if (!Filter->FileInFilter(fd))
+			if (!Filter->FileInFilter(fd,nullptr,&(fd.strFileName)))
 				continue;
 		}
 
@@ -2177,7 +2177,8 @@
 
 	if (UseFilter)
 	{
-		if (!Filter->FileInFilter(SrcData))
+		const string strSrc = string(Src);
+		if (!Filter->FileInFilter(SrcData,nullptr,&strSrc))
 			return COPY_NOFILTER;
 	}
 
@@ -4079,7 +4080,7 @@
 			//  ��������� ��������� ������
 			if (UseFilter)
 			{
-				if (!Filter->FileInFilter(fd))
+				if (!Filter->FileInFilter(fd,nullptr,&(fd.strFileName)))
 					continue;
 			}
 
Index: dirinfo.cpp
===================================================================
--- dirinfo.cpp	(revision 6911)
+++ dirinfo.cpp	(working copy)
@@ -197,7 +197,7 @@
 			*/
 			if ((Flags&GETDIRINFO_USEFILTER))
 			{
-				if (!Filter->FileInFilter(FindData))
+				if (!Filter->FileInFilter(FindData,nullptr,&strFullName))
 					continue;
 			}
 
Index: FarEng.hlf.m4
===================================================================
--- FarEng.hlf.m4	(revision 6911)
+++ FarEng.hlf.m4	(working copy)
@@ -1737,7 +1737,14 @@
                    #Virtual# attribute is not used in Windows
                    2000/XP/2003.
 
+   #Has more than one hardlink#
 
+                   Used only on disks with NTFS file system. Condition 
+                   evaluates to true, if piece of data, which current 
+                   file is pointing, is also pointed by, at least, 
+                   one another file.
+
+
     To quickly disable one or several conditions, uncheck the corresponding
 checkboxes. The #Reset# button will clear all of the filter conditions.
 
Index: farlang.templ.m4
===================================================================
--- farlang.templ.m4	(revision 6911)
+++ farlang.templ.m4	(working copy)
@@ -19603,6 +19603,15 @@
 "<="
 "<="
 
+MFileHardLinksCount
+"Болee одной жёсткой ссылки"
+"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+
 MFileFilterDate
 "&Дата/Время:"
 "Da&te/Time:"
Index: FarRus.hlf.m4
===================================================================
--- FarRus.hlf.m4	(revision 6911)
+++ FarRus.hlf.m4	(working copy)
@@ -1758,6 +1758,13 @@
                    только на дисках с файловой системой NTFS. Атрибут
                    #Виртуальный# не используется в Windows 2000/XP/2003.
 
+   #Более одной жесткой ссылки#
+
+                   Используется только на дисках с файловой системой NTFS.
+                   Условие истинно, когда на элемент данных, на который 
+                   ссылается текущий файл, ссылается, хотя бы, еще один файл.
+
+
     Для быстрого отключения одного или нескольких условий фильтра отключите
 соответствующие опции. Клавиша #Очистить# сбросит все условия фильтра.
 
Index: filefilter.cpp
===================================================================
--- filefilter.cpp	(revision 6911)
+++ filefilter.cpp	(working copy)
@@ -610,7 +610,7 @@
 	CurrentTime = current.QuadPart;
 }
 
-bool FileFilter::FileInFilter(const FileListItem& fli,enumFileInFilterType *foundType)
+bool FileFilter::FileInFilter(const FileListItem& fli,enumFileInFilterType *foundType, const string* strFullName)
 {
 	FAR_FIND_DATA_EX fde;
 	fde.dwFileAttributes=fli.FileAttr;
@@ -622,10 +622,10 @@
 	fde.nPackSize=fli.PackSize;
 	fde.strFileName=fli.strName;
 	fde.strAlternateFileName=fli.strShortName;
-	return FileInFilter(fde,foundType);
+	return FileInFilter(fde,foundType,strFullName);
 }
 
-bool FileFilter::FileInFilter(const FAR_FIND_DATA_EX& fde,enumFileInFilterType *foundType)
+bool FileFilter::FileInFilter(const FAR_FIND_DATA_EX& fde,enumFileInFilterType *foundType, const string* strFullName)
 {
 	enumFileFilterFlagsType FFFT = GetFFFT();
 	bool bFound=false;
@@ -655,7 +655,7 @@
 					bAnyFolderIncludeFound = bAnyFolderIncludeFound || !(AttrClear&FILE_ATTRIBUTE_DIRECTORY);
 			}
 
-			if (CurFilterData->FileInFilter(fde, CurrentTime))
+			if (CurFilterData->FileInFilter(fde, CurrentTime, strFullName))
 			{
 				bFound = true;
 
@@ -683,7 +683,7 @@
 				bAnyFolderIncludeFound = true;
 			}
 
-			if (bFolder && FoldersFilter.FileInFilter(fde, CurrentTime))
+			if (bFolder && FoldersFilter.FileInFilter(fde, CurrentTime, strFullName)) 
 			{
 				bFound = true;
 
@@ -711,7 +711,7 @@
 			if (bFolder) //����-����� ������� �� ����� �� �� �����
 				continue;
 
-			if (CurFilterData->FileInFilter(fde, CurrentTime))
+			if (CurFilterData->FileInFilter(fde, CurrentTime, strFullName)) 
 			{
 				bFound = true;
 
@@ -749,11 +749,11 @@
 	return !bAnyIncludeFound;
 }
 
-bool FileFilter::FileInFilter(const PluginPanelItem& fd,enumFileInFilterType *foundType)
+bool FileFilter::FileInFilter(const PluginPanelItem& fd,enumFileInFilterType *foundType,const string* strFullName)
 {
 	FAR_FIND_DATA_EX fde;
 	PluginPanelItemToFindDataEx(&fd,&fde);
-	return FileInFilter(fde,foundType);
+	return FileInFilter(fde,foundType,strFullName);
 }
 
 bool FileFilter::IsEnabledOnPanel()
@@ -852,6 +852,14 @@
 			cfg->GetValue(key,L"UseSize",&UseSize);
 			NewFilter->SetSize(UseSize!=0, strSizeAbove, strSizeBelow);
 
+			unsigned __int64 UseHardLinks = 0;
+			cfg->GetValue(key,L"UseHardLinks",&UseHardLinks);
+			unsigned __int64 HardLinksAbove;
+			cfg->GetValue(key,L"HardLinksAbove",&HardLinksAbove);
+			unsigned __int64 HardLinksBelow;
+			cfg->GetValue(key,L"HardLinksAbove",&HardLinksBelow);
+			NewFilter->SetHardLinks(UseHardLinks!=0,HardLinksAbove,HardLinksBelow);
+
 			unsigned __int64 UseAttr = 1;
 			cfg->GetValue(key,L"UseAttr",&UseAttr);
 			unsigned __int64 AttrSet = 0;
@@ -948,6 +956,10 @@
 		cfg->SetValue(key,L"UseSize",CurFilterData->GetSize(&SizeAbove, &SizeBelow)?1:0);
 		cfg->SetValue(key,L"SizeAboveS",SizeAbove);
 		cfg->SetValue(key,L"SizeBelowS",SizeBelow);
+		unsigned __int64 HardLinksAbove,HardLinksBelow;
+		cfg->SetValue(key,L"UseHardLinks",CurFilterData->GetHardLinks(&HardLinksAbove,&HardLinksBelow)?1:0);
+		cfg->SetValue(key,L"HardLinksAboveS",SizeAbove);
+		cfg->SetValue(key,L"HardLinksBelowS",SizeBelow);
 		DWORD AttrSet, AttrClear;
 		cfg->SetValue(key,L"UseAttr",CurFilterData->GetAttr(&AttrSet, &AttrClear)?1:0);
 		cfg->SetValue(key,L"AttrSet",AttrSet);
Index: filefilter.hpp
===================================================================
--- filefilter.hpp	(revision 6911)
+++ filefilter.hpp	(working copy)
@@ -68,9 +68,9 @@
 
 		bool FilterEdit();
 		void UpdateCurrentTime();
-		bool FileInFilter(const FileListItem& fli,enumFileInFilterType *foundType=nullptr);
-		bool FileInFilter(const FAR_FIND_DATA_EX& fde,enumFileInFilterType *foundType=nullptr);
-		bool FileInFilter(const PluginPanelItem& fd,enumFileInFilterType *foundType=nullptr);
+		bool FileInFilter(const FileListItem& fli,enumFileInFilterType *foundType=nullptr,const string* strFullName=nullptr);
+		bool FileInFilter(const FAR_FIND_DATA_EX& fde,enumFileInFilterType *foundType=nullptr,const string* strFullName=nullptr);
+		bool FileInFilter(const PluginPanelItem& fd,enumFileInFilterType *foundType=nullptr,const string* strFullName=nullptr);
 		bool IsEnabledOnPanel();
 
 		static void InitFilter();
Index: filefilterparams.cpp
===================================================================
--- filefilterparams.cpp	(revision 6911)
+++ filefilterparams.cpp	(working copy)
@@ -51,11 +51,13 @@
 #include "strmix.hpp"
 #include "mix.hpp"
 #include "console.hpp"
+#include "flink.hpp"
 
 FileFilterParams::FileFilterParams()
 {
 	SetMask(1,L"*");
 	SetSize(0,L"",L"");
+	SetHardLinks(0,0,0);
 	ClearStruct(FDate);
 	ClearStruct(FAttr);
 	ClearStruct(FHighlight.Colors);
@@ -207,6 +209,13 @@
 	FSize.SizeBelowReal=ConvertFileSizeString(FSize.SizeBelow);
 }
 
+void FileFilterParams::SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow)
+{
+	FHardLinks.Used=Used;
+	FHardLinks.CountAbove=HardLinksAbove;
+	FHardLinks.CountBelow=HardLinksBelow;
+}
+
 void FileFilterParams::SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear)
 {
 	FAttr.Used=Used;
@@ -266,6 +275,16 @@
 	return FSize.Used;
 }
 
+bool FileFilterParams::GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const
+{
+	if (HardLinksAbove)
+		*HardLinksAbove = FHardLinks.CountAbove;
+	if (HardLinksBelow)
+		*HardLinksBelow = FHardLinks.CountBelow;
+	return FHardLinks.Used;
+}
+
+
 bool FileFilterParams::GetAttr(DWORD *AttrSet, DWORD *AttrClear) const
 {
 	if (AttrSet)
@@ -287,7 +306,7 @@
 	return FHighlight.Colors.MarkChar;
 }
 
-bool FileFilterParams::FileInFilter(const FileListItem& fli, unsigned __int64 CurrentTime)
+bool FileFilterParams::FileInFilter(const FileListItem& fli, unsigned __int64 CurrentTime, const string* strFullName)
 {
 	FAR_FIND_DATA_EX fde;
 	fde.dwFileAttributes=fli.FileAttr;
@@ -299,10 +318,10 @@
 	fde.nPackSize=fli.PackSize;
 	fde.strFileName=fli.strName;
 	fde.strAlternateFileName=fli.strShortName;
-	return FileInFilter(fde, CurrentTime);
+	return FileInFilter(fde, CurrentTime,strFullName);
 }
 
-bool FileFilterParams::FileInFilter(const FAR_FIND_DATA_EX& fde, unsigned __int64 CurrentTime)
+bool FileFilterParams::FileInFilter(const FAR_FIND_DATA_EX& fde, unsigned __int64 CurrentTime,const string* strFileName)
 {
 	// ����� �������� ��������� ����� �����?
 	if (FAttr.Used)
@@ -332,6 +351,14 @@
 		}
 	}
 
+	// ����� �������� ��������� ������ ����� �� ���� �����?
+	// ���� ���, ��� �������� �������, ����������� ��������� ��� ����� "����� ���� ��� ����"
+	if (FHardLinks.Used && strFileName!=nullptr && (fde.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==false)
+	{
+		if (GetNumberOfLinks(*strFileName)<2) 
+			return false;
+	}
+
 	// ����� �������� ������� ����� �����?
 	if (FDate.Used)
 	{
@@ -402,11 +429,11 @@
 	return true;
 }
 
-bool FileFilterParams::FileInFilter(const PluginPanelItem& fd, unsigned __int64 CurrentTime)
+bool FileFilterParams::FileInFilter(const PluginPanelItem& fd, unsigned __int64 CurrentTime, const string* strFullName)
 {
 	FAR_FIND_DATA_EX fde;
 	PluginPanelItemToFindDataEx(&fd,&fde);
-	return FileInFilter(fde, CurrentTime);
+	return FileInFilter(fde, CurrentTime,strFullName);
 }
 
 //��������������� ����� �� ������� ����� ��� ������ �������.
@@ -429,16 +456,16 @@
 		FILE_ATTRIBUTE_OFFLINE,
 		FILE_ATTRIBUTE_VIRTUAL,
 	};
-	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-4.4s %c %s";
 	const wchar_t DownArrow=0x2193;
 	const wchar_t *Name, *Mask;
 	wchar_t MarkChar[]=L"\" \"";
 	DWORD IncludeAttr, ExcludeAttr;
-	bool UseMask, UseSize, UseDate, RelativeDate;
+	bool UseMask, UseSize, UseHardLinks, UseDate, RelativeDate;
 
 	if (bPanelType)
 	{
@@ -447,7 +474,7 @@
 		Mask=FMask;
 		IncludeAttr=0;
 		ExcludeAttr=FILE_ATTRIBUTE_DIRECTORY;
-		RelativeDate=UseDate=UseSize=false;
+		RelativeDate=UseDate=UseSize=UseHardLinks=false;
 	}
 	else
 	{
@@ -464,6 +491,7 @@
 
 		UseSize=FF->GetSize(nullptr,nullptr);
 		UseDate=FF->GetDate(nullptr,nullptr,nullptr,&RelativeDate);
+		UseHardLinks=FF->GetHardLinks(nullptr,nullptr);
 	}
 
 	wchar_t Attr[ARRAYSIZE(AttrC)*2] = {};
@@ -481,7 +509,7 @@
 			*Ptr=*(Ptr+1)=L'.';
 	}
 
-	wchar_t SizeDate[4] = L"...";
+	wchar_t SizeDate[5] = L"....";
 
 	if (UseSize)
 	{
@@ -496,16 +524,21 @@
 			SizeDate[1]=L'D';
 	}
 
+	if (UseHardLinks)
+	{
+		SizeDate[2]=L'H';
+	}
+
 	if (bHighlightType)
 	{
 		if (FF->GetContinueProcessing())
-			SizeDate[2]=DownArrow;
+			SizeDate[3]=DownArrow;
 
 		strDest.Format(Format2, MarkChar, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], UseMask ? Mask : L"");
 	}
 	else
 	{
-		SizeDate[2]=0;
+		SizeDate[3]=0;
 
 		if (!Hotkey && !bPanelType)
 		{
@@ -594,6 +627,10 @@
 
 	ID_FF_SEPARATOR5,
 
+	ID_FF_HARDLINKS,
+
+	ID_FF_SEPARATOR6,
+
 	ID_FF_OK,
 	ID_FF_RESET,
 	ID_FF_CANCEL,
@@ -747,6 +784,7 @@
 				SendDlgMessage(hDlg,DM_LISTSETCURPOS,ID_FF_DATETYPE,&LPos);
 				SendDlgMessage(hDlg,DM_SETCHECK,ID_FF_MATCHMASK,ToPtr(BSTATE_CHECKED));
 				SendDlgMessage(hDlg,DM_SETCHECK,ID_FF_MATCHSIZE,ToPtr(BSTATE_UNCHECKED));
+				SendDlgMessage(hDlg,DM_SETCHECK,ID_FF_HARDLINKS,ToPtr(BSTATE_UNCHECKED));
 				SendDlgMessage(hDlg,DM_SETCHECK,ID_FF_MATCHDATE,ToPtr(BSTATE_UNCHECKED));
 				SendDlgMessage(hDlg,DM_SETCHECK,ID_FF_DATERELATIVE,ToPtr(BSTATE_UNCHECKED));
 				FilterDlgRelativeDateItemsUpdate(hDlg, true);
@@ -895,7 +933,7 @@
 	strTimeMask.Format(L"99%c99%c99%c999",TimeSeparator,TimeSeparator,DecimalSeparator);
 	FarDialogItem FilterDlgData[]=
 	{
-		{DI_DOUBLEBOX,3,1,76,18,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
+		{DI_DOUBLEBOX,3,1,76,20,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
 
 		{DI_TEXT,5,2,0,2,0,nullptr,nullptr,DIF_FOCUS,MSG(MFileFilterName)},
 		{DI_EDIT,5,2,74,2,0,FilterNameHistoryName,nullptr,DIF_HISTORY,L""},
@@ -966,10 +1004,13 @@
 
 		{DI_TEXT,0,16,0,16,0,nullptr,nullptr,DIF_SEPARATOR,L""},
 
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
+		{DI_CHECKBOX,5,17,0,17,0,nullptr,nullptr,0,MSG(MFileHardLinksCount)},//�������� ���� ������� � �����
+		{DI_TEXT,0,18,0,18,0,nullptr,nullptr,DIF_SEPARATOR,L""},// � ����������
+
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
 	};
 	FilterDlgData[0].Data=MSG(ColorConfig?MFileHilightTitle:MFileFilterTitle);
 	MakeDialogItemsEx(FilterDlgData,FilterDlg);
@@ -1032,6 +1073,7 @@
 	FilterDlg[ID_FF_MATCHSIZE].Selected=FF->GetSize(&SizeAbove,&SizeBelow)?1:0;
 	FilterDlg[ID_FF_SIZEFROMEDIT].strData=SizeAbove;
 	FilterDlg[ID_FF_SIZETOEDIT].strData=SizeBelow;
+	FilterDlg[ID_FF_HARDLINKS].Selected=FF->GetHardLinks(nullptr,nullptr)?1:0; //���� ��� � ������� ����� ���� ����������� ������� ������
 
 	if (!FilterDlg[ID_FF_MATCHSIZE].Selected)
 		for (int i=ID_FF_SIZEFROMSIGN; i <= ID_FF_SIZETOEDIT; i++)
@@ -1151,6 +1193,7 @@
 			FF->SetSize(FilterDlg[ID_FF_MATCHSIZE].Selected!=0,
 			            FilterDlg[ID_FF_SIZEFROMEDIT].strData,
 			            FilterDlg[ID_FF_SIZETOEDIT].strData);
+			FF->SetHardLinks(FilterDlg[ID_FF_HARDLINKS].Selected!=0,0,0); //���� ������������� ����� ���� ����������� ��������
 			bRelative = FilterDlg[ID_FF_DATERELATIVE].Selected!=0;
 
 			LPWSTR TimeBefore = FilterDlg[ID_FF_TIMEBEFOREEDIT].strData.GetBuffer();
Index: filefilterparams.hpp
===================================================================
--- filefilterparams.hpp	(revision 6911)
+++ filefilterparams.hpp	(working copy)
@@ -105,6 +105,13 @@
 			bool Used;
 		} FSize;
 
+		struct // ���� ��������� � ������, ���� ����� ��������� ������ �����. ���� ��� ������ ��������� ����� ���� Used � �������� �������� ������� "����� ���� ��� ����"
+		{
+			bool Used;
+			unsigned __int64 CountAbove; //��� ��� ������ ��� wchar_t � ������������� � ����� �� ������������? 
+			unsigned __int64 CountBelow; 
+		} FHardLinks;
+
 		struct
 		{
 			bool Used;
@@ -131,6 +138,7 @@
 		void SetMask(bool Used, const wchar_t *Mask);
 		void SetDate(bool Used, DWORD DateType, FILETIME DateAfter, FILETIME DateBefore, bool bRelative);
 		void SetSize(bool Used, const wchar_t *SizeAbove, const wchar_t *SizeBelow);
+		void SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow);
 		void SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear);
 		void SetColors(HighlightDataColor *Colors);
 		void SetSortGroup(int SortGroup) { FHighlight.SortGroup = SortGroup; }
@@ -142,6 +150,7 @@
 		bool  GetMask(const wchar_t **Mask) const;
 		bool  GetDate(DWORD *DateType, FILETIME *DateAfter, FILETIME *DateBefore, bool *bRelative) const;
 		bool  GetSize(const wchar_t **SizeAbove, const wchar_t **SizeBelow) const;
+		bool  GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const;
 		bool  GetAttr(DWORD *AttrSet, DWORD *AttrClear) const;
 		void  GetColors(HighlightDataColor *Colors) const;
 		int   GetMarkChar() const;
@@ -153,9 +162,9 @@
 		// �������� �� ���� fd ��� ������� �������������� ������.
 		// ��������� true  - ��������;
 		//            false - �� ��������.
-		bool FileInFilter(const FileListItem& fli, unsigned __int64 CurrentTime);
-		bool FileInFilter(const FAR_FIND_DATA_EX& fde, unsigned __int64 CurrentTime);
-		bool FileInFilter(const PluginPanelItem& fd, unsigned __int64 CurrentTime);
+		bool FileInFilter(const FileListItem& fli, unsigned __int64 CurrentTime,const string* strFullName=nullptr); //Used only in highlight.cpp - strFullName is not necessary here, should I remove it?
+		bool FileInFilter(const FAR_FIND_DATA_EX& fde, unsigned __int64 CurrentTime,const string* strFullName=nullptr); //Used in dirinfo, copy, findfile
+		bool FileInFilter(const PluginPanelItem& fd, unsigned __int64 CurrentTime,const string* strFullName=nullptr); //Don't used anywhere?? strFullName is unnecessary here, shoul I remove it?
 };
 
 bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig=false);
Index: filelist.cpp
===================================================================
--- filelist.cpp	(revision 6911)
+++ filelist.cpp	(working copy)
@@ -3265,7 +3265,7 @@
 
 bool FileList::FileInFilter(long idxItem)
 {
-	if ( ( (DWORD)idxItem < (DWORD)FileCount ) && ( !Filter || !Filter->IsEnabledOnPanel() || Filter->FileInFilter(*ListData[idxItem]) ) )
+	if ( ( (DWORD)idxItem < (DWORD)FileCount ) && ( !Filter || !Filter->IsEnabledOnPanel() || Filter->FileInFilter(*ListData[idxItem],nullptr,&ListData[idxItem]->strName) ) )
 		return true;
 	return false;
 }
@@ -3905,7 +3905,7 @@
 			else
 			{
 				if (bUseFilter)
-					Match=Filter.FileInFilter(*CurPtr);
+					Match=Filter.FileInFilter(*CurPtr,nullptr,&(CurPtr->strName));
 				else
 					Match=FileMask.Compare((ShowShortNames && !CurPtr->strShortName.IsEmpty() ? CurPtr->strShortName:CurPtr->strName));
 			}
Index: findfile.cpp
===================================================================
--- findfile.cpp	(revision 6911)
+++ findfile.cpp	(working copy)
@@ -2597,7 +2597,7 @@
 				{
 					enumFileInFilterType foundType;
 
-					if (!Filter->FileInFilter(FindData,&foundType))
+					if (!Filter->FileInFilter(FindData,&foundType,&strFullName))
 					{
 						// ��� ������, ���� �� ������ � ����� ��� ������ � Exclude-�����
 						if ((FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && foundType==FIFT_EXCLUDE)
@@ -2695,7 +2695,7 @@
 			strFullName = strPluginSearchPath;
 			strFullName += strCurName;
 
-			if (!UseFilter || Filter->FileInFilter(*CurPanelItem))
+			if (!UseFilter || Filter->FileInFilter(*CurPanelItem),nullptr,&strFullName)
 			{
 				if (((CurPanelItem->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strFindStr.IsEmpty()) ||
 				        (!(CurPanelItem->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !strFindStr.IsEmpty()))
@@ -2721,7 +2721,7 @@
 
 			if ((CurPanelItem->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
 			        StrCmp(strCurName,L".") && !TestParentFolderName(strCurName) &&
-			        (!UseFilter || Filter->FileInFilter(*CurPanelItem)) &&
+			        (!UseFilter || Filter->FileInFilter(*CurPanelItem,nullptr,&strCurName)) &&
 			        (SearchMode!=FINDAREA_SELECTED || RecurseLevel!=1 ||
 			         CtrlObject->Cp()->ActivePanel->IsSelected(strCurName)))
 			{
Index: flupdate.cpp
===================================================================
--- flupdate.cpp	(revision 6911)
+++ flupdate.cpp	(working copy)
@@ -270,7 +270,7 @@
 	{
 		FindErrorCode = GetLastError();
 
-		if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata)))
+		if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata,nullptr,&(fdata.strFileName))))
 		{
 			if (FileCount>=AllocatedCount)
 			{
@@ -767,9 +767,12 @@
 		CurListData->Clear();
 
 		if (UseFilter && !(Info.Flags & OPIF_DISABLEFILTER))
+		{
 			//if (!(CurPanelData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
-			if (!Filter->FileInFilter(PanelData[i]))
+			string strFileName = string(PanelData[i].FileName);
+			if (!Filter->FileInFilter(PanelData[i],nullptr,&strFileName))
 				continue;
+		}
 
 		if (!Opt.ShowHidden && (PanelData[i].FileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
 			continue;
Index: hilight.cpp
===================================================================
--- hilight.cpp	(revision 6911)
+++ hilight.cpp	(working copy)
@@ -71,6 +71,7 @@
 	*ContinueProcessing,
 	*UseDate,*DateType,*DateAfter,*DateBefore,*DateRelative,
 	*UseSize,*SizeAbove,*SizeBelow,
+	*UseHardLinks,*HardLinksAbove,*HardLinksBelow,
 	*HighlightEdit,*HighlightList;
 };
 
@@ -92,6 +93,7 @@
 	L"ContinueProcessing",
 	L"UseDate",L"DateType",L"DateAfter",L"DateBefore",L"DateRelative",
 	L"UseSize",L"SizeAboveS",L"SizeBelowS",
+	L"UseHardLinks",L"HardLinksAbove",L"HardLinksBelow",
 	L"HighlightEdit",L"HighlightList"
 };
 
@@ -238,6 +240,14 @@
 	cfg->GetValue(key,HLS.UseSize,&UseSize);
 	HData->SetSize(UseSize!=0, strSizeAbove, strSizeBelow);
 
+	unsigned __int64 UseHardLinks = 0;
+	unsigned __int64 HardLinksAbove = 0;
+	unsigned __int64 HardLinksBelow = 0;
+	cfg->GetValue(key,HLS.UseHardLinks,&UseHardLinks);
+	cfg->GetValue(key,HLS.HardLinksAbove,&HardLinksAbove);
+	cfg->GetValue(key,HLS.HardLinksBelow,&HardLinksBelow);
+	HData->SetHardLinks(UseHardLinks!=0,HardLinksAbove,HardLinksBelow);
+
 	if (bSortGroup)
 	{
 		unsigned __int64 UseAttr = 1;
@@ -485,7 +495,7 @@
 			if (UseAttrHighlighting && CurHiData->GetMask(nullptr))
 				continue;
 
-			if (CurHiData->FileInFilter(fli, CurrentTime))
+			if (CurHiData->FileInFilter(fli, CurrentTime, &fli.strName))
 			{
 				HighlightDataColor TempColors;
 				CurHiData->GetColors(&TempColors);
@@ -506,7 +516,7 @@
 	{
 		FileFilterParams *CurGroupData=HiData.getItem(i);
 
-		if (CurGroupData->FileInFilter(*fli, CurrentTime))
+		if (CurGroupData->FileInFilter(*fli, CurrentTime, &((*fli).strName)))
 			return(CurGroupData->GetSortGroup());
 	}
 
@@ -514,7 +524,7 @@
 	{
 		FileFilterParams *CurGroupData=HiData.getItem(i);
 
-		if (CurGroupData->FileInFilter(*fli, CurrentTime))
+		if (CurGroupData->FileInFilter(*fli, CurrentTime, &((*fli).strName)))
 			return(CurGroupData->GetSortGroup());
 	}
 
@@ -881,6 +891,10 @@
 	cfg->SetValue(key,HLS.UseSize,CurHiData->GetSize(&SizeAbove, &SizeBelow)?1:0);
 	cfg->SetValue(key,HLS.SizeAbove,SizeAbove);
 	cfg->SetValue(key,HLS.SizeBelow,SizeBelow);
+	unsigned __int64 HardLinksAbove, HardLinksBelow;
+	cfg->SetValue(key,HLS.UseHardLinks,CurHiData->GetHardLinks(&HardLinksAbove, &HardLinksBelow)?1:0);
+	cfg->SetValue(key,HLS.HardLinksAbove,HardLinksAbove);
+	cfg->SetValue(key,HLS.HardLinksBelow,HardLinksBelow);
 	DWORD AttrSet, AttrClear;
 	cfg->SetValue(key,HLS.UseAttr,CurHiData->GetAttr(&AttrSet, &AttrClear)?1:0);
 	cfg->SetValue(key,(bSortGroup?HLS.AttrSet:HLS.IncludeAttributes),AttrSet);
Index: plugapi.cpp
===================================================================
--- plugapi.cpp	(revision 6911)
+++ plugapi.cpp	(working copy)
@@ -2472,8 +2472,8 @@
 		{
 			if (!Param2)
 				break;
-
-			return Filter->FileInFilter(*(const PluginPanelItem *)Param2) ? TRUE : FALSE;
+			const string strFileName = string(((const PluginPanelItem *)Param2)->FileName);
+			return Filter->FileInFilter(*(const PluginPanelItem *)Param2,nullptr,&strFileName) ? TRUE : FALSE;
 		}
 	}
 
hardlink_filter_patch_v3.diff (25,743 bytes)   

Sergey Karpukhin

2011-12-03 10:56

reporter   bugnote:0008039

Last edited: 2011-12-04 07:50

hardlink_filter_patch_v3.diff (патч для ревизии 6911)

Добавил сброс нового чекбокса в окошке с фильтром при нажатии на ресет

Исправил ошибки с неверными результатами работы нового фильтра при поиске и копировании: добавил новый параметр по умолчанию const string*strFullName в методы FileFilterParams::FileInFilter() и FileFilter::FileInFilter() и добавил передачу нового параметра в фильтр из всех нужных процедур

Добавил информацию о новом параметре фильтра в русскую и английскую справку

Проверил работоспособность при следующий сценариях использования:
1. Подсветка файлов через Files Highlighting
2. Выбор файлов с фильтром через (+)
3. Поиск файлов с фильтром через (Alt+F7)
4. Копирование файлов с фильтром (F5)
5. Создание ссылок по группе с фильтром (Alt+F6)
6. Скрытие файлов из панели с фильтром (Ctrl+I)

Что дальше?

DrKnS

2011-12-03 17:46

administrator   bugnote:0008040

> Проверил работоспособность при следующий сценариях исползования:
> 3. Поиск файлов с фильтром через (Alt+F7)


И как, вот это работало? :)
> if (!UseFilter || Filter->FileInFilter(*CurPanelItem),nullptr,&strFullName)


build 2277.

Sergey Karpukhin

2011-12-04 08:05

reporter   bugnote:0008044

Я так понял это в куске который касается метода ScanPluginTree(), для поиска в панелях плагинов, эмулирующий файловые системы? У меня голая сборка без плагинов :(, поэтому, пока что, я проверял поиск только на реальных папках/файлах.

Вроде бы плагины от второй версии не подходят к третьей, а подходят только от старой неюникодовой версии, через враппер?

Не могли бы вы подсказать плагин, который уже работает с тройкой и на котором лучше всего можно будет проверить и отладить этот кусок кода?

DrKnS

2011-12-04 08:17

administrator   bugnote:0008045

Увы, не могу.

А плагины от Far 2 тоже можно использовать через внешний враппер - http://code.google.com/p/conemu-maximus5/downloads/detail?name=Far3Wrap.1.20.%282204%29.7z

Sergey Karpukhin

2011-12-04 09:59

reporter   bugnote:0008047

Last edited: 2011-12-04 10:03

> И как, вот это работало? :)
>> if (!UseFilter || Filter->FileInFilter(*CurPanelItem),nullptr,&strFullName)

Блин, вот дурень я, сначала подумал что для плагинов там не тот путь передавался, все дела, полез за враппером, плагин подобрал, отлаживать начал...

... и только потом эту скобку заметил не на том месте =)

Как ни странно компилировалось без ошибок и замечаний. Ради интереса теперь придется идти ковыряться в с++ стандарте, и смотреть как ведет себя составное выражение типа if(<expr1> || <expr2>,<expr3>) или что-нибудь в этом роде

никогда не думал что параметры в функциях по умолчанию могут позволить так элегантно "выстрелить себе в ногу"

Sergey Karpukhin

2011-12-04 10:09

reporter   bugnote:0008048

В итоге все таки проверил новую опцию фильтра и на плагине (Temporary Panel) - работает.

DrKnS

2011-12-04 10:19

administrator   bugnote:0008049

> Как ни странно компилировалось без ошибок и замечаний.

"любая случайная последовательность символов является корректной программой на C" :)

> В итоге все таки проверил новую опцию фильтра и на плагине (Temporary Panel) - работает.

Закрываем?

Sergey Karpukhin

2011-12-04 10:27

reporter   bugnote:0008050

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

Сегодня уже не успею все сделать - завтра отпишусь и тогда можно закрывать будет

Sergey Karpukhin

2011-12-05 13:12

reporter  

hardlink_filter_patch_addon_v1.diff (7,241 bytes)   
Index: copy.cpp
===================================================================
--- copy.cpp	(revision 6923)
+++ copy.cpp	(working copy)
@@ -2023,7 +2023,8 @@
 					// ������ ��������� ������� ����������� - ���� ������� ������ �
 					// ������ ��� �����������, �� ������� ��������� � ��� � �� ���
 					// ����������.
-					if (!Filter->FileInFilter(SrcData))
+					// ��� ���� �� ��� strFullName - ��� ����� �������� � "���������������� �����������" �� ������ ��� ���������� "��_�����_�_��������_�����_����������"="��_����_��������_�_������_����������"
+					if (!Filter->FileInFilter(SrcData,nullptr,strFullName)) 
 					{
 						ScTree.SkipDir();
 						continue;
Index: dirinfo.cpp
===================================================================
--- dirinfo.cpp	(revision 6923)
+++ dirinfo.cpp	(working copy)
@@ -186,7 +186,8 @@
 				// ���� ������� �� �������� ��� ����� �� ��� ���� �������
 				// ��������� - ���� ��� �������� ������ total
 				// �� ���� (mantis 551)
-				if (!Filter->FileInFilter(FindData))
+				// ��� ���� �� ��� strFullName - ��� ����� �������� � "���������������� �����������" �� ������ ��� ���������� "��_�����_�_��������_�����_����������"="��_����_��������_�_������_����������"
+				if (!Filter->FileInFilter(FindData,nullptr,strFullName)) 
 					ScTree.SkipDir();
 			}
 		}
Index: filefilter.cpp
===================================================================
--- filefilter.cpp	(revision 6923)
+++ filefilter.cpp	(working copy)
@@ -610,7 +610,7 @@
 	CurrentTime = current.QuadPart;
 }
 
-bool FileFilter::FileInFilter(const FileListItem& fli,enumFileInFilterType *foundType, const wchar_t* FullName)
+bool FileFilter::FileInFilter(const FileListItem& fli,enumFileInFilterType *foundType)
 {
 	FAR_FIND_DATA_EX fde;
 	fde.dwFileAttributes=fli.FileAttr;
@@ -622,7 +622,7 @@
 	fde.nPackSize=fli.PackSize;
 	fde.strFileName=fli.strName;
 	fde.strAlternateFileName=fli.strShortName;
-	return FileInFilter(fde, foundType, FullName);
+	return FileInFilter(fde, foundType, fli.strName);
 }
 
 bool FileFilter::FileInFilter(const FAR_FIND_DATA_EX& fde,enumFileInFilterType *foundType, const wchar_t* FullName)
@@ -749,11 +749,11 @@
 	return !bAnyIncludeFound;
 }
 
-bool FileFilter::FileInFilter(const PluginPanelItem& fd,enumFileInFilterType *foundType,const wchar_t* FullName)
+bool FileFilter::FileInFilter(const PluginPanelItem& fd,enumFileInFilterType *foundType)
 {
 	FAR_FIND_DATA_EX fde;
 	PluginPanelItemToFindDataEx(&fd,&fde);
-	return FileInFilter(fde, foundType, FullName);
+	return FileInFilter(fde, foundType, fd.FileName);
 }
 
 bool FileFilter::IsEnabledOnPanel()
Index: filefilter.hpp
===================================================================
--- filefilter.hpp	(revision 6923)
+++ filefilter.hpp	(working copy)
@@ -68,9 +68,9 @@
 
 		bool FilterEdit();
 		void UpdateCurrentTime();
-		bool FileInFilter(const FileListItem& fli, enumFileInFilterType *foundType=nullptr, const wchar_t* FullName=nullptr);
+		bool FileInFilter(const FileListItem& fli, enumFileInFilterType *foundType=nullptr);
 		bool FileInFilter(const FAR_FIND_DATA_EX& fde, enumFileInFilterType *foundType=nullptr, const wchar_t* FullName=nullptr);
-		bool FileInFilter(const PluginPanelItem& fd, enumFileInFilterType *foundType=nullptr, const wchar_t* FullName=nullptr);
+		bool FileInFilter(const PluginPanelItem& fd, enumFileInFilterType *foundType=nullptr);
 		bool IsEnabledOnPanel();
 
 		static void InitFilter();
Index: filefilterparams.cpp
===================================================================
--- filefilterparams.cpp	(revision 6923)
+++ filefilterparams.cpp	(working copy)
@@ -318,7 +318,7 @@
 	fde.nPackSize=fli.PackSize;
 	fde.strFileName=fli.strName;
 	fde.strAlternateFileName=fli.strShortName;
-	return FileInFilter(fde, CurrentTime);
+	return FileInFilter(fde, CurrentTime, fli.strName);
 }
 
 bool FileFilterParams::FileInFilter(const FAR_FIND_DATA_EX& fde, unsigned __int64 CurrentTime,const wchar_t* FullName)
@@ -355,11 +355,16 @@
 	// ���� ���, ��� �������� �������, ����������� ��������� ��� ����� "����� ���� ��� ����"
 	if (FHardLinks.Used)
 	{
+		//����� ��� ���� ��������� ���� �� ������� ����� �� ������ �������, ���� �� ����� ������/���������� ������ ���� ������ �� ����������� �����?
 		if (fde.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 		{
 			return false;
 		}
-
+		//��� ���� ���������:
+		//� ������� ��� ����� � copy.cpp � dirinfo.cpp ��� �� ���������� FullName � ��� ��� ������ ����������� FullName/strFileName.CPtr() ����� �� �������
+		//����� � ������� ��� �������� ���� FileInFilter(const FAR_FIND_DATA_EX ...), ���� ��� ���� ���������� FullName
+		//�� �� ����� �����, � ���� ��� ��� ���� ����� �����������, ���� ������� ������� ������� � ������
+		//��� �������� ���� ����� �� ������ FullName, ���� ��� �� ��������, �� ������ ��������� �������.
 		const wchar_t* Name = FullName? FullName : fde.strFileName.CPtr();
 		if (GetNumberOfLinks(Name) < 2)
 		{
@@ -441,7 +446,7 @@
 {
 	FAR_FIND_DATA_EX fde;
 	PluginPanelItemToFindDataEx(&fd, &fde);
-	return FileInFilter(fde, CurrentTime);
+	return FileInFilter(fde, CurrentTime, fd.FileName);
 }
 
 //��������������� ����� �� ������� ����� ��� ������ �������.
Index: findfile.cpp
===================================================================
--- findfile.cpp	(revision 6923)
+++ findfile.cpp	(working copy)
@@ -2695,7 +2695,7 @@
 			strFullName = strPluginSearchPath;
 			strFullName += strCurName;
 
-			if (!UseFilter || Filter->FileInFilter(*CurPanelItem,nullptr, strFullName))
+			if (!UseFilter || Filter->FileInFilter(*CurPanelItem)) //<-- �� ����� � �������� ������ FileInFilter �� CurPanelItem
 			{
 				if (((CurPanelItem->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strFindStr.IsEmpty()) ||
 				        (!(CurPanelItem->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !strFindStr.IsEmpty()))
Index: flupdate.cpp
===================================================================
--- flupdate.cpp	(revision 6923)
+++ flupdate.cpp	(working copy)
@@ -270,7 +270,7 @@
 	{
 		FindErrorCode = GetLastError();
 
-		if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata)))
+		if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata,nullptr,fdata.strFileName)))
 		{
 			if (FileCount>=AllocatedCount)
 			{
Index: plugapi.cpp
===================================================================
--- plugapi.cpp	(revision 6923)
+++ plugapi.cpp	(working copy)
@@ -2472,7 +2472,7 @@
 		{
 			if (!Param2)
 				break;
-			return Filter->FileInFilter(*reinterpret_cast<const PluginPanelItem*>(Param2)) ? TRUE : FALSE;
+			return Filter->FileInFilter(*reinterpret_cast<const PluginPanelItem*>(Param2)) ? TRUE : FALSE; //<--- ��� �� ������ ������� FullName, ���������� ���, ��� � ����� ������� ������ �� ������ FileInFilter �� PluginPanelItem
 		}
 	}
 

Sergey Karpukhin

2011-12-05 13:18

reporter   bugnote:0008054

Last edited: 2011-12-05 13:31

hardlink_filter_patch_addon_v1.diff (for revision 6923)

Я тут еще немного поковырялся, убрал передачу FullName из 2 их 3 перегруженных версий FileInFilter - нужные параметры вытаскиваем явно, внутри методов.

bool FileInFilter(const FileListItem& ...);
bool FileInFilter(const PluginPanelItem& ...);

Осталось только разобраться с реализацией bool FileFilterParams::FileInFilter(const FAR_FIND_DATA_EX& fde ...); я там моменты некоторые в виде коментариев высказал.

DrKnS

2011-12-05 15:02

administrator   bugnote:0008055

- if (!UseFilter || Filter->FileInFilter(*CurPanelItem,nullptr, strFullName))
+ if (!UseFilter || Filter->FileInFilter(*CurPanelItem)) //<-- имя файла мы достанем внутри FileInFilter из CurPanelItem

strFullName - это strPluginSearchPath + СurPanelItem->FileName.
внутри FileInFilter мы можем достать только СurPanelItem->FileName.
разве это равнозначная замена?

> //может все таки перенесем тест на атрибут папки во внешнее условие, чтобы на папки наличие/отсутствие данной опции фильтра не действовало вообще?

Если тест на атрибут папки перенести во внешнее условие, то все папки будут _включены_ в фильтр.
Идём в раскраску файлов, создаем новую запись для файлов с "more than one hardlink", назначаем ей красный цвет например.
Выходим и видим покрасневшие папки.
Чтобы исправить - надо возвращаться, включать обработку атрибутов и явно снимать птичку с "Directory". Какой смысл в этих действиях, если папка по определению не имеет хардлинков?

Sergey Karpukhin

2011-12-05 16:11

reporter   bugnote:0008057

Last edited: 2011-12-05 16:14

>> if (!UseFilter || Filter->FileInFilter(*CurPanelItem)) //<-- имя файла мы >>достанем внутри FileInFilter из CurPanelItem

> strFullName - это strPluginSearchPath + СurPanelItem->FileName.
> внутри FileInFilter мы можем достать только СurPanelItem->FileName.
> разве это равнозначная замена?

Я дебажил с плагином TemporaryPanel - на момент вызова FileInFilter, получалось что CurPanelItem=strFullName=полный путь к файлу с путями.

Посему я так понял, что плагины реализующие "файловые системы" должны хранить полный путь в структуре, описывающей каждый "виртуальный файл, поэтому попытался убрать избыточную передачу данных.

Может быть плагин нетипичный/нерепрезентативный? В других, получается, только имя передается?


по поводу теста на папку - согласен, оставляем ваш вариант.
будем ли оставлять свободу выбора между FileName/FullFileName в FileInFilter?

DrKnS

2011-12-05 16:58

administrator   bugnote:0008058

Увы, не знаю других плагинов, реализующих реальные ФС, кроме TmpPanel.


> будем ли оставлять свободу выбора между FileName/FullFileName в FileInFilter?

убрал.

Sergey Karpukhin

2011-12-06 04:40

reporter   bugnote:0008059

Все, проверил все пункты на последней версии из репозитория, можно закрывать.

Issue History

Date Modified Username Field Change
2009-12-19 17:05 user379 New Issue
2009-12-19 17:06 user379 Tag Attached: hard link
2010-02-15 16:55 alexy Project Far Manager => Wishes
2010-11-24 06:51 DrKnS Relationship added has duplicate 0001601
2011-09-10 10:45 samlyukov Note Added: 0007648
2011-12-01 12:32 Sergey Karpukhin File Added: hardlink_filter_patch.diff
2011-12-01 12:50 Sergey Karpukhin Note Added: 0008021
2011-12-01 12:55 Sergey Karpukhin Note Added: 0008022
2011-12-01 12:55 Sergey Karpukhin Status new => feedback
2011-12-01 12:56 Sergey Karpukhin Note Edited: 0008022
2011-12-01 13:14 DrKnS Note Added: 0008023
2011-12-01 13:25 Sergey Karpukhin Note Added: 0008024
2011-12-01 13:30 DrKnS Note Added: 0008025
2011-12-01 13:34 Sergey Karpukhin Note Added: 0008026
2011-12-01 13:36 DrKnS Note Added: 0008027
2011-12-01 19:07 DrKnS Relationship added duplicate of 0000084
2011-12-01 19:08 DrKnS Relationship deleted has duplicate 0001601
2011-12-02 03:00 Sergey Karpukhin File Added: hardlink_filter_patch_v2.diff
2011-12-02 03:17 Sergey Karpukhin Note Added: 0008029
2011-12-02 06:53 DrKnS Note Added: 0008031
2011-12-02 08:28 Sergey Karpukhin Note Added: 0008033
2011-12-02 09:25 DrKnS Note Added: 0008034
2011-12-03 10:46 Sergey Karpukhin File Added: hardlink_filter_patch_v3.diff
2011-12-03 10:56 Sergey Karpukhin Note Added: 0008039
2011-12-03 10:57 Sergey Karpukhin Note Edited: 0008039
2011-12-03 17:46 DrKnS Note Added: 0008040
2011-12-03 17:46 DrKnS Assigned To => DrKnS
2011-12-03 17:46 DrKnS Status feedback => assigned
2011-12-03 17:48 DrKnS Status assigned => feedback
2011-12-04 07:50 Sergey Karpukhin Note Edited: 0008039
2011-12-04 08:05 Sergey Karpukhin Note Added: 0008044
2011-12-04 08:17 DrKnS Note Added: 0008045
2011-12-04 09:59 Sergey Karpukhin Note Added: 0008047
2011-12-04 10:00 Sergey Karpukhin Note Edited: 0008047
2011-12-04 10:03 Sergey Karpukhin Note Edited: 0008047
2011-12-04 10:09 Sergey Karpukhin Note Added: 0008048
2011-12-04 10:19 DrKnS Note Added: 0008049
2011-12-04 10:27 Sergey Karpukhin Note Added: 0008050
2011-12-05 13:12 Sergey Karpukhin File Added: hardlink_filter_patch_addon_v1.diff
2011-12-05 13:18 Sergey Karpukhin Note Added: 0008054
2011-12-05 13:31 Sergey Karpukhin Note Edited: 0008054
2011-12-05 15:02 DrKnS Note Added: 0008055
2011-12-05 16:11 Sergey Karpukhin Note Added: 0008057
2011-12-05 16:14 Sergey Karpukhin Note Edited: 0008057
2011-12-05 16:58 DrKnS Note Added: 0008058
2011-12-06 04:40 Sergey Karpukhin Note Added: 0008059
2011-12-23 08:29 alexy Build => 2283
2011-12-23 08:29 alexy Status feedback => closed
2011-12-23 08:29 alexy Resolution open => fixed
2011-12-23 08:29 alexy Fixed in Version => 3.0
2013-02-03 00:33 alexy Severity minor => feature