Beispiel #1
0
void FileList::CreatePluginItemList(PluginPanelItem *(&ItemList),int &ItemNumber,BOOL AddTwoDot)
{
	if (!ListData)
		return;

	long SaveSelPosition=GetSelPosition;
	long OldLastSelPosition=LastSelPosition;
	string strSelName;
	DWORD FileAttr;
	ItemNumber=0;
	ItemList=new PluginPanelItem[SelFileCount+1]();

	if (ItemList)
	{
		GetSelName(nullptr,FileAttr);

		while (GetSelName(&strSelName,FileAttr))
			if ((!(FileAttr & FILE_ATTRIBUTE_DIRECTORY) || !TestParentFolderName(strSelName))
			        && LastSelPosition>=0 && LastSelPosition<FileCount)
			{
				FileListToPluginItem(ListData[LastSelPosition],ItemList+ItemNumber);
				ItemNumber++;
			}

		if (AddTwoDot && !ItemNumber && (FileAttr & FILE_ATTRIBUTE_DIRECTORY)) // это про ".."
		{
			FileListToPluginItem(ListData[0],ItemList+ItemNumber);
			//ItemList->FindData.lpwszFileName = xf_wcsdup (ListData[0]->strName);
			//ItemList->FindData.dwFileAttributes=ListData[0]->FileAttr;
			ItemNumber++;
		}
	}

	LastSelPosition=OldLastSelPosition;
	GetSelPosition=SaveSelPosition;
}
Beispiel #2
0
void FileList::UpdatePlugin(int KeepSelection, int IgnoreVisible)
{
	_ALGO(CleverSysLog clv(L"FileList::UpdatePlugin"));
	_ALGO(SysLog(L"(KeepSelection=%d, IgnoreVisible=%d)",KeepSelection,IgnoreVisible));

	if (!IsVisible() && !IgnoreVisible)
	{
		UpdateRequired=TRUE;
		UpdateRequiredMode=KeepSelection;
		return;
	}

	DizRead=FALSE;
	FileListItem *CurPtr, **OldData=0;
	string strCurName, strNextCurName;
	int OldFileCount=0;
	StopFSWatcher();
	LastCurFile=-1;
	OpenPanelInfo Info;
	CtrlObject->Plugins->GetOpenPanelInfo(hPlugin,&Info);

	FreeDiskSize=0;
	if (Opt.ShowPanelFree)
	{
		if (Info.Flags & OPIF_REALNAMES)
		{
			unsigned __int64 TotalSize,TotalFree;
			if (!apiGetDiskSize(strCurDir,&TotalSize,&TotalFree,&FreeDiskSize))
				FreeDiskSize=0;
		}
		else if (Info.Flags & OPIF_USEFREESIZE)
			FreeDiskSize=Info.FreeSize;
	}

	PluginPanelItem *PanelData=nullptr;
	size_t PluginFileCount;

	if (!CtrlObject->Plugins->GetFindData(hPlugin,&PanelData,&PluginFileCount,0))
	{
		DeleteListData(ListData,FileCount);
		PopPlugin(TRUE);
		Update(KeepSelection);

		// WARP> явный хак, но очень способствует - восстанавливает позицию на панели при ошибке чтения архива.
		if (!PrevDataList.Empty())
			GoToFile((*PrevDataList.Last())->strPrevName);

		return;
	}

	size_t PrevSelFileCount=SelFileCount;
	SelFileCount=0;
	SelFileSize=0;
	TotalFileCount=0;
	TotalFileSize=0;
	CacheSelIndex=-1;
	CacheSelClearIndex=-1;
	strPluginDizName.Clear();

	if (FileCount>0)
	{
		CurPtr=ListData[CurFile];
		strCurName = CurPtr->strName;

		if (CurPtr->Selected)
		{
			for (int i=CurFile+1; i < FileCount; i++)
			{
				CurPtr = ListData[i];

				if (!CurPtr->Selected)
				{
					strNextCurName = CurPtr->strName;
					break;
				}
			}
		}
	}
	else if (Info.Flags & OPIF_ADDDOTS)
	{
		strCurName = L"..";
	}

	if (KeepSelection || PrevSelFileCount>0)
	{
		OldData=ListData;
		OldFileCount=FileCount;
	}
	else
	{
		DeleteListData(ListData,FileCount);
	}

	FileCount=static_cast<int>(PluginFileCount);
	ListData=(FileListItem**)xf_malloc(sizeof(FileListItem*)*(FileCount+1));

	if (!ListData)
	{
		FileCount=0;
		return;
	}

	if (!Filter)
		Filter=new FileFilter(this,FFT_PANEL);

	//Рефреш текущему времени для фильтра перед началом операции
	Filter->UpdateCurrentTime();
	CtrlObject->HiFiles->UpdateCurrentTime();
	int DotsPresent=FALSE;
	int FileListCount=0;
	bool UseFilter=Filter->IsEnabledOnPanel();

	for (int i=0; i < FileCount; i++)
	{
		ListData[FileListCount] = new FileListItem;
		FileListItem *CurListData=ListData[FileListCount];
		CurListData->Clear();

		if (UseFilter && !(Info.Flags & OPIF_DISABLEFILTER))
		{
			//if (!(CurPanelData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			if (!Filter->FileInFilter(PanelData[i]))
				continue;
		}

		if (!Opt.ShowHidden && (PanelData[i].FileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
			continue;

		//ClearStruct(*CurListData);
		PluginToFileListItem(&PanelData[i],CurListData);
		CurListData->Position=i;

		if (!(Info.Flags & OPIF_DISABLESORTGROUPS)/* && !(CurListData->FileAttr & FILE_ATTRIBUTE_DIRECTORY)*/)
			CurListData->SortGroup=CtrlObject->HiFiles->GetGroup(CurListData);
		else
			CurListData->SortGroup=DEFAULT_SORT_GROUP;

		if (!CurListData->DizText)
		{
			CurListData->DeleteDiz=FALSE;
			//CurListData->DizText=nullptr;
		}

		if (TestParentFolderName(CurListData->strName))
		{
			DotsPresent=TRUE;
			CurListData->FileAttr|=FILE_ATTRIBUTE_DIRECTORY;
		}
		else if (!(CurListData->FileAttr & FILE_ATTRIBUTE_DIRECTORY))
		{
			TotalFileCount++;
		}

		TotalFileSize += CurListData->FileSize;
		FileListCount++;
	}

	if (!(Info.Flags & OPIF_DISABLEHIGHLIGHTING) || (Info.Flags & OPIF_USEATTRHIGHLIGHTING))
		CtrlObject->HiFiles->GetHiColor(ListData,FileListCount,(Info.Flags&OPIF_USEATTRHIGHLIGHTING)!=0);

	FileCount=FileListCount;

	if ((Info.Flags & OPIF_ADDDOTS) && !DotsPresent)
	{
		ListData[FileCount] = new FileListItem;
		CurPtr = ListData[FileCount];
		CurPtr->Clear();
		AddParentPoint(CurPtr,FileCount);

		if (!(Info.Flags & OPIF_DISABLEHIGHLIGHTING) || (Info.Flags & OPIF_USEATTRHIGHLIGHTING))
			CtrlObject->HiFiles->GetHiColor(&CurPtr,1,(Info.Flags&OPIF_USEATTRHIGHLIGHTING)!=0);

		if (Info.HostFile && *Info.HostFile)
		{
			FAR_FIND_DATA_EX FindData;

			if (apiGetFindDataEx(Info.HostFile, FindData))
			{
				CurPtr->WriteTime=FindData.ftLastWriteTime;
				CurPtr->CreationTime=FindData.ftCreationTime;
				CurPtr->AccessTime=FindData.ftLastAccessTime;
				CurPtr->ChangeTime=FindData.ftChangeTime;
			}
		}

		FileCount++;
	}

	if (CurFile >= FileCount)
		CurFile = FileCount ? FileCount-1 : 0;

	/* $ 25.02.2001 VVM
	    ! Не считывать повторно список файлов с панели плагина */
	if (IsColumnDisplayed(DIZ_COLUMN))
		ReadDiz(PanelData,static_cast<int>(PluginFileCount),RDF_NO_UPDATE);

	CorrectPosition();
	CtrlObject->Plugins->FreeFindData(hPlugin,PanelData,PluginFileCount);

	if (KeepSelection || PrevSelFileCount>0)
	{
		MoveSelection(ListData,FileCount,OldData,OldFileCount);
		DeleteListData(OldData,OldFileCount);
	}

	if (!KeepSelection && PrevSelFileCount>0)
	{
		SaveSelection();
		ClearSelection();
	}

	SortFileList(FALSE);

	if (CurFile>=FileCount || StrCmpI(ListData[CurFile]->strName,strCurName))
		if (!GoToFile(strCurName) && !strNextCurName.IsEmpty())
			GoToFile(strNextCurName);

	SetTitle();
}
Beispiel #3
0
void FileList::ShowFileList(int Fast)
{
	if (Locked())
	{
		CorrectPosition();
		return;
	}

	string strTitle;
	string strInfoCurDir;
	int Length;
	OpenPanelInfo Info;

	if (PanelMode==PLUGIN_PANEL)
	{
		if (ProcessPluginEvent(FE_REDRAW,nullptr))
			return;

		CtrlObject->Plugins->GetOpenPanelInfo(hPlugin,&Info);
		strInfoCurDir=Info.CurDir;
	}

	bool CurFullScreen=IsFullScreen();
	PrepareViewSettings(ViewMode,&Info);
	CorrectPosition();

	if (CurFullScreen!=IsFullScreen())
	{
		CtrlObject->Cp()->SetScreenPosition();
		CtrlObject->Cp()->GetAnotherPanel(this)->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
	}

	SetScreen(X1+1,Y1+1,X2-1,Y2-1,L' ',ColorIndexToColor(COL_PANELTEXT));
	Box(X1,Y1,X2,Y2,ColorIndexToColor(COL_PANELBOX),DOUBLE_BOX);

	if (Opt.ShowColumnTitles)
	{
//    SetScreen(X1+1,Y1+1,X2-1,Y1+1,' ',COL_PANELTEXT);
		SetColor(COL_PANELTEXT); //???
		//GotoXY(X1+1,Y1+1);
		//FS<<fmt::Width(X2-X1-1)<<L"";
	}

	for (int I=0,ColumnPos=X1+1; I<ViewSettings.ColumnCount; I++)
	{
		if (ViewSettings.ColumnWidth[I]<0)
			continue;

		if (Opt.ShowColumnTitles)
		{
			LNGID IDMessage=MColumnUnknown;

			switch (ViewSettings.ColumnType[I] & 0xff)
			{
				case NAME_COLUMN:
					IDMessage=MColumnName;
					break;
				case EXTENSION_COLUMN:
					IDMessage=MColumnExtension;
					break;
				case SIZE_COLUMN:
					IDMessage=MColumnSize;
					break;
				case PACKED_COLUMN:
					IDMessage=MColumnAlocatedSize;
					break;
				case DATE_COLUMN:
					IDMessage=MColumnDate;
					break;
				case TIME_COLUMN:
					IDMessage=MColumnTime;
					break;
				case WDATE_COLUMN:
					IDMessage=MColumnWrited;
					break;
				case CDATE_COLUMN:
					IDMessage=MColumnCreated;
					break;
				case ADATE_COLUMN:
					IDMessage=MColumnAccessed;
					break;
				case CHDATE_COLUMN:
					IDMessage=MColumnChanged;
					break;
				case ATTR_COLUMN:
					IDMessage=MColumnAttr;
					break;
				case DIZ_COLUMN:
					IDMessage=MColumnDescription;
					break;
				case OWNER_COLUMN:
					IDMessage=MColumnOwner;
					break;
				case NUMLINK_COLUMN:
					IDMessage=MColumnMumLinks;
					break;
				case NUMSTREAMS_COLUMN:
					IDMessage=MColumnNumStreams;
					break;
				case STREAMSSIZE_COLUMN:
					IDMessage=MColumnStreamsSize;
					break;
			}

			strTitle=MSG(IDMessage);

			if (PanelMode==PLUGIN_PANEL && Info.PanelModesArray &&
			        ViewMode<static_cast<int>(Info.PanelModesNumber) &&
			        Info.PanelModesArray[ViewMode].ColumnTitles)
			{
				const wchar_t *NewTitle=Info.PanelModesArray[ViewMode].ColumnTitles[I];

				if (NewTitle)
					strTitle=NewTitle;
			}

			string strTitleMsg;
			CenterStr(strTitle,strTitleMsg,ViewSettings.ColumnWidth[I]);
			SetColor(COL_PANELCOLUMNTITLE);
			GotoXY(ColumnPos,Y1+1);
			FS<<fmt::Precision(ViewSettings.ColumnWidth[I])<<strTitleMsg;
		}

		if (I>=ViewSettings.ColumnCount-1)
			break;

		if (ViewSettings.ColumnWidth[I+1]<0)
			continue;

		SetColor(COL_PANELBOX);
		ColumnPos+=ViewSettings.ColumnWidth[I];
		GotoXY(ColumnPos,Y1);

		bool DoubleLine = Opt.DoubleGlobalColumnSeparator && (!((I+1)%ColumnsInGlobal));

		BoxText(BoxSymbols[DoubleLine?BS_T_H2V2:BS_T_H2V1]);

		if (Opt.ShowColumnTitles)
		{
			GotoXY(ColumnPos,Y1+1);
			BoxText(BoxSymbols[DoubleLine?BS_V2:BS_V1]);
		}

		if (!Opt.ShowPanelStatus)
		{
			GotoXY(ColumnPos,Y2);
			BoxText(BoxSymbols[DoubleLine?BS_B_H2V2:BS_B_H2V1]);
		}

		ColumnPos++;
	}

	int NextX1=X1+1;

	if (Opt.ShowSortMode)
	{
		static int SortModes[]={UNSORTED,BY_NAME,BY_EXT,BY_MTIME,BY_CTIME,
		                        BY_ATIME,BY_CHTIME,BY_SIZE,BY_DIZ,BY_OWNER,
		                        BY_COMPRESSEDSIZE,BY_NUMLINKS,
		                        BY_NUMSTREAMS,BY_STREAMSSIZE,
		                        BY_FULLNAME,BY_CUSTOMDATA
		                       };
		static LNGID SortStrings[]={MMenuUnsorted,MMenuSortByName,
		                          MMenuSortByExt,MMenuSortByWrite,MMenuSortByCreation,
		                          MMenuSortByAccess,MMenuSortByChange,MMenuSortBySize,MMenuSortByDiz,MMenuSortByOwner,
		                          MMenuSortByAllocatedSize,MMenuSortByNumLinks,MMenuSortByNumStreams,MMenuSortByStreamsSize,
		                          MMenuSortByFullName,MMenuSortByCustomData
		                         };

		for (size_t I=0; I<ARRAYSIZE(SortModes); I++)
		{
			if (SortModes[I]==SortMode)
			{
				const wchar_t *SortStr=MSG(SortStrings[I]);
				const wchar_t *Ch=wcschr(SortStr,L'&');

				if (Ch)
				{
					if (Opt.ShowColumnTitles)
						GotoXY(NextX1,Y1+1);
					else
						GotoXY(NextX1,Y1);

					SetColor(COL_PANELCOLUMNTITLE);
					OutCharacter[0]=SortOrder==1 ? Lower(Ch[1]):Upper(Ch[1]);
					Text(OutCharacter);
					NextX1++;

					if (Filter && Filter->IsEnabledOnPanel())
					{
						OutCharacter[0]=L'*';
						Text(OutCharacter);
						NextX1++;
					}
				}

				break;
			}
		}
	}

	/* <режимы сортировки> */
	if (/*GetNumericSort() || GetCaseSensitiveSort() || GetSortGroups() || */GetSelectedFirstMode())
	{
		if (Opt.ShowColumnTitles)
			GotoXY(NextX1,Y1+1);
		else
			GotoXY(NextX1,Y1);

		SetColor(COL_PANELCOLUMNTITLE);
		wchar_t *PtrOutCharacter=OutCharacter;
		*PtrOutCharacter=0;

		//if (GetSelectedFirstMode())
			*PtrOutCharacter++=L'^';

		/*
		    if(GetNumericSort())
		      *PtrOutCharacter++=L'#';
		    if(GetSortGroups())
		      *PtrOutCharacter++=L'@';
		*/
		/*
		if(GetCaseSensitiveSort())
		{

		}
		*/
		*PtrOutCharacter=0;
		Text(OutCharacter);
		PtrOutCharacter[1]=0;
	}

	/* </режимы сортировки> */

	if (!Fast && GetFocus())
	{
		if (PanelMode==PLUGIN_PANEL)
			CtrlObject->CmdLine->SetCurDir(Info.CurDir);
		else
			CtrlObject->CmdLine->SetCurDir(strCurDir);

		CtrlObject->CmdLine->Show();
	}

	int TitleX2=Opt.Clock && !Opt.ShowMenuBar ? Min(ScrX-4,X2):X2;
	int TruncSize=TitleX2-X1-3;

	if (!Opt.ShowColumnTitles && Opt.ShowSortMode && Filter && Filter->IsEnabledOnPanel())
		TruncSize-=2;

	GetTitle(strTitle,TruncSize,2);//,(PanelMode==PLUGIN_PANEL?0:2));
	Length=(int)strTitle.GetLength();
	int ClockCorrection=FALSE;

	if ((Opt.Clock && !Opt.ShowMenuBar) && TitleX2==ScrX-4)
	{
		ClockCorrection=TRUE;
		TitleX2+=4;
	}

	int TitleX=X1+(TitleX2-X1+1-Length)/2;

	if (ClockCorrection)
	{
		int Overlap=TitleX+Length-TitleX2+5;

		if (Overlap > 0)
			TitleX-=Overlap;
	}

	if (TitleX <= X1)
		TitleX = X1+1;

	SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE);
	GotoXY(TitleX,Y1);
	Text(strTitle);

	if (!FileCount)
	{
		SetScreen(X1+1,Y2-1,X2-1,Y2-1,L' ',ColorIndexToColor(COL_PANELTEXT));
		SetColor(COL_PANELTEXT); //???
		//GotoXY(X1+1,Y2-1);
		//FS<<fmt::Width(X2-X1-1)<<L"";
	}

	if (PanelMode==PLUGIN_PANEL && FileCount>0 && (Info.Flags & OPIF_REALNAMES))
	{
		if (!strInfoCurDir.IsEmpty())
		{
			strCurDir = strInfoCurDir;
		}
		else
		{
			if (!TestParentFolderName(ListData[CurFile]->strName))
			{
				strCurDir=ListData[CurFile]->strName;
				size_t pos;

				if (FindLastSlash(pos,strCurDir))
				{
					if (pos)
					{
						if (strCurDir.At(pos-1)!=L':')
							strCurDir.SetLength(pos);
						else
							strCurDir.SetLength(pos+1);
					}
				}
			}
			else
			{
				strCurDir = strOriginalCurDir;
			}
		}

		if (GetFocus())
		{
			CtrlObject->CmdLine->SetCurDir(strCurDir);
			CtrlObject->CmdLine->Show();
		}
	}

	if ((Opt.ShowPanelTotals || Opt.ShowPanelFree) &&
	        (Opt.ShowPanelStatus || !SelFileCount))
	{
		ShowTotalSize(Info);
	}

	ShowList(FALSE,0);
	ShowSelectedSize();

	if (Opt.ShowPanelScrollbar)
	{
		SetColor(COL_PANELSCROLLBAR);
		ScrollBarEx(X2,Y1+1+Opt.ShowColumnTitles,Height,Round(CurTopFile,Columns),Round(FileCount,Columns));
	}

	ShowScreensCount();

	if (!ProcessingPluginCommand && LastCurFile!=CurFile)
	{
		LastCurFile=CurFile;
		UpdateViewPanel();
	}

	if (PanelMode==PLUGIN_PANEL)
		CtrlObject->Cp()->RedrawKeyBar();
}
Beispiel #4
0
void ShellDelete(Panel *SrcPanel,int Wipe)
{
	ChangePriority ChPriority(Opt.DelThreadPriority);
	TPreRedrawFuncGuard preRedrawFuncGuard(PR_ShellDeleteMsg);
	FAR_FIND_DATA_EX FindData;
	string strDeleteFilesMsg;
	string strSelName;
	string strSelShortName;
	string strDizName;
	string strFullName;
	DWORD FileAttr;
	int SelCount,UpdateDiz;
	int DizPresent;
	int Ret;
	BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE;
	int Opt_DeleteToRecycleBin=Opt.DeleteToRecycleBin;
	/*& 31.05.2001 OT Запретить перерисовку текущего фрейма*/
	Frame *FrameFromLaunched=FrameManager->GetCurrentFrame();
	FrameFromLaunched->Lock();
	DeleteAllFolders=!Opt.Confirm.DeleteFolder;
	UpdateDiz=(Opt.Diz.UpdateMode==DIZ_UPDATE_ALWAYS ||
	           (SrcPanel->IsDizDisplayed() &&
	            Opt.Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED));

	if (!(SelCount=SrcPanel->GetSelCount()))
		goto done;

	// Удаление в корзину только для  FIXED-дисков
	{
		string strRoot;
//    char FSysNameSrc[NM];
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);
		ConvertNameToFull(strSelName, strRoot);
		GetPathRoot(strRoot,strRoot);

//_SVS(SysLog(L"Del: SelName='%s' Root='%s'",SelName,Root));
		if (Opt.DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED)
			Opt.DeleteToRecycleBin=0;
	}

	if (SelCount==1)
	{
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);

		if (TestParentFolderName(strSelName) || strSelName.IsEmpty())
		{
			NeedUpdate=FALSE;
			goto done;
		}

		strDeleteFilesMsg = strSelName;
	}
	else
	{
		// в зависимости от числа ставим нужное окончание
		const wchar_t *Ends;
		wchar_t StrItems[16];
		_itow(SelCount,StrItems,10);
		Ends=MSG(MAskDeleteItemsA);
		int LenItems=StrLength(StrItems);

		if (LenItems > 0)
		{
			if ((LenItems >= 2 && StrItems[LenItems-2] == L'1') ||
			        StrItems[LenItems-1] >= L'5' ||
			        StrItems[LenItems-1] == L'0')
				Ends=MSG(MAskDeleteItemsS);
			else if (StrItems[LenItems-1] == L'1')
				Ends=MSG(MAskDeleteItems0);
		}

		strDeleteFilesMsg.Format(MSG(MAskDeleteItems),SelCount,Ends);
	}

	Ret=1;

	//   Обработка "удаления" линков
	if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) && SelCount==1)
	{
		string strJuncName;
		ConvertNameToFull(strSelName,strJuncName);

		if (GetReparsePointInfo(strJuncName, strJuncName)) // ? SelName ?
		{
			NormalizeSymlinkName(strJuncName);
			//SetMessageHelp(L"DeleteLink");
			string strAskDeleteLink=MSG(MAskDeleteLink);
			DWORD dwAttr=apiGetFileAttributes(strJuncName);

			if (dwAttr!=INVALID_FILE_ATTRIBUTES)
			{
				strAskDeleteLink+=L" ";
				strAskDeleteLink+=dwAttr&FILE_ATTRIBUTE_DIRECTORY?MSG(MAskDeleteLinkFolder):MSG(MAskDeleteLinkFile);
			}

			Ret=Message(0,3,MSG(MDeleteLinkTitle),
			            strDeleteFilesMsg,
			            strAskDeleteLink,
			            strJuncName,
			            MSG(MDeleteLinkDelete),MSG(MDeleteLinkUnlink),MSG(MCancel));

			if (Ret == 1)
			{
				ConvertNameToFull(strSelName, strJuncName);

				if (Opt.Confirm.Delete)
				{
					; //  ;-%
				}

				if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) != -1) //JuncName?
				{
					DeleteReparsePoint(strJuncName);
					ShellUpdatePanels(SrcPanel,NeedSetUpADir);
				}

				goto done;
			}

			if (Ret )
				goto done;
		}
	}

	if (Ret && (Opt.Confirm.Delete || SelCount>1 || (FileAttr & FILE_ATTRIBUTE_DIRECTORY)))
	{
		const wchar_t *DelMsg;
		const wchar_t *TitleMsg=MSG(Wipe?MDeleteWipeTitle:MDeleteTitle);
		/* $ 05.01.2001 IS
		   ! Косметика в сообщениях - разные сообщения в зависимости от того,
		     какие и сколько элементов выделено.
		*/
		BOOL folder=(FileAttr & FILE_ATTRIBUTE_DIRECTORY);

		if (SelCount==1)
		{
			if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
				DelMsg=MSG(folder?MAskWipeFolder:MAskWipeFile);
			else
			{
				if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
					DelMsg=MSG(folder?MAskDeleteRecycleFolder:MAskDeleteRecycleFile);
				else
					DelMsg=MSG(folder?MAskDeleteFolder:MAskDeleteFile);
			}
		}
		else
		{
			if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
			{
				DelMsg=MSG(MAskWipe);
				TitleMsg=MSG(MDeleteWipeTitle);
			}
			else if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
				DelMsg=MSG(MAskDeleteRecycle);
			else
				DelMsg=MSG(MAskDelete);
		}

		SetMessageHelp(L"DeleteFile");

		if (Message(0,2,TitleMsg,DelMsg,strDeleteFilesMsg,MSG(Wipe?MDeleteWipe:Opt.DeleteToRecycleBin?MDeleteRecycle:MDelete),MSG(MCancel)))
		{
			NeedUpdate=FALSE;
			goto done;
		}
	}

	if (Opt.Confirm.Delete && SelCount>1)
	{
		//SaveScreen SaveScr;
		SetCursorType(FALSE,0);
		SetMessageHelp(L"DeleteFile");

		if (Message(MSG_WARNING,2,MSG(Wipe?MWipeFilesTitle:MDeleteFilesTitle),MSG(Wipe?MAskWipe:MAskDelete),
		            strDeleteFilesMsg,MSG(MDeleteFileAll),MSG(MDeleteFileCancel)))
		{
			NeedUpdate=FALSE;
			goto done;
		}
	}

	if (UpdateDiz)
		SrcPanel->ReadDiz();

	SrcPanel->GetDizName(strDizName);
	DizPresent=(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES);
	DeleteTitle = new ConsoleTitle(MSG(MDeletingTitle));

	if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) == -1)
		goto done;

	if (SrcPanel->GetType()==TREE_PANEL)
		FarChDir(L"\\");

	{
		TaskBar TB;
		wakeful W;
		bool Cancel=false;
		//SaveScreen SaveScr;
		SetCursorType(FALSE,0);
		ReadOnlyDeleteMode=-1;
		SkipMode=-1;
		SkipWipeMode=-1;
		SkipFoldersMode=-1;
		ULONG ItemsCount=0;
		ProcessedItems=0;

		if (Opt.DelOpt.DelShowTotal)
		{
			SrcPanel->GetSelName(nullptr,FileAttr);
			DWORD StartTime=GetTickCount();
			bool FirstTime=true;

			while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel)
			{
				if (!(FileAttr&FILE_ATTRIBUTE_REPARSE_POINT))
				{
					if (FileAttr&FILE_ATTRIBUTE_DIRECTORY)
					{
						DWORD CurTime=GetTickCount();

						if (CurTime-StartTime>RedrawTimeout || FirstTime)
						{
							StartTime=CurTime;
							FirstTime=false;

							if (CheckForEscSilent() && ConfirmAbortOp())
							{
								Cancel=true;
								break;
							}

							ShellDeleteMsg(strSelName,Wipe,-1);
						}

						ULONG CurrentFileCount,CurrentDirCount,ClusterSize;
						UINT64 FileSize,CompressedFileSize,RealSize;

						if (GetDirInfo(nullptr,strSelName,CurrentDirCount,CurrentFileCount,FileSize,CompressedFileSize,RealSize,ClusterSize,-1,nullptr,0)>0)
						{
							ItemsCount+=CurrentFileCount+CurrentDirCount+1;
						}
						else
						{
							Cancel=true;
						}
					}
					else
					{
						ItemsCount++;
					}
				}
			}
		}

		SrcPanel->GetSelName(nullptr,FileAttr);
		DWORD StartTime=GetTickCount();
		bool FirstTime=true;

		while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel)
		{
			int Length=(int)strSelName.GetLength();

			if (!Length || (strSelName.At(0)==L'\\' && Length<2) ||
			        (strSelName.At(1)==L':' && Length<4))
				continue;

			DWORD CurTime=GetTickCount();

			if (CurTime-StartTime>RedrawTimeout || FirstTime)
			{
				StartTime=CurTime;
				FirstTime=false;

				if (CheckForEscSilent() && ConfirmAbortOp())
				{
					Cancel=true;
					break;
				}

				ShellDeleteMsg(strSelName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1);
			}

			if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
			{
				if (!DeleteAllFolders)
				{
					ConvertNameToFull(strSelName, strFullName);

					if (TestFolder(strFullName) == TSTFLD_NOTEMPTY)
					{
						int MsgCode=0;

						// для symlink`а не нужно подтверждение
						if (!(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
							MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle),
							                MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName,
							                MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll),
							                MSG(MDeleteFileSkip),MSG(MDeleteFileCancel));

						if (MsgCode<0 || MsgCode==3)
						{
							NeedSetUpADir=FALSE;
							break;
						}

						if (MsgCode==1)
							DeleteAllFolders=1;

						if (MsgCode==2)
							continue;
					}
				}

				bool DirSymLink=(FileAttr&FILE_ATTRIBUTE_DIRECTORY && FileAttr&FILE_ATTRIBUTE_REPARSE_POINT);

				if (!DirSymLink && (!Opt.DeleteToRecycleBin || Wipe))
				{
					string strFullName;
					ScanTree ScTree(TRUE,TRUE,FALSE);
					string strSelFullName;

					if (IsAbsolutePath(strSelName))
					{
						strSelFullName=strSelName;
					}
					else
					{
						SrcPanel->GetCurDir(strSelFullName);
						AddEndSlash(strSelFullName);
						strSelFullName+=strSelName;
					}

					ScTree.SetFindPath(strSelFullName,L"*", 0);
					DWORD StartTime=GetTickCount();

					while (ScTree.GetNextName(&FindData,strFullName))
					{
						DWORD CurTime=GetTickCount();

						if (CurTime-StartTime>RedrawTimeout)
						{
							StartTime=CurTime;

							if (CheckForEscSilent())
							{
								int AbortOp = ConfirmAbortOp();

								if (AbortOp)
								{
									Cancel=true;
									break;
								}
							}

							ShellDeleteMsg(strFullName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1);
						}

						if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
						{
							if (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
							{
								if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
									apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL);

								int MsgCode=ERemoveDirectory(strFullName,Wipe);

								if (MsgCode==DELETE_CANCEL)
								{
									Cancel=true;
									break;
								}
								else if (MsgCode==DELETE_SKIP)
								{
									ScTree.SkipDir();
									continue;
								}

								TreeList::DelTreeName(strFullName);

								if (UpdateDiz)
									SrcPanel->DeleteDiz(strFullName,strSelShortName);

								continue;
							}

							if (!DeleteAllFolders && !ScTree.IsDirSearchDone() && TestFolder(strFullName) == TSTFLD_NOTEMPTY)
							{
								int MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle),
								                    MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName,
								                    MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll),
								                    MSG(MDeleteFileSkip),MSG(MDeleteFileCancel));

								if (MsgCode<0 || MsgCode==3)
								{
									Cancel=true;
									break;
								}

								if (MsgCode==1)
									DeleteAllFolders=1;

								if (MsgCode==2)
								{
									ScTree.SkipDir();
									continue;
								}
							}

							if (ScTree.IsDirSearchDone())
							{
								if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
									apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL);

								int MsgCode=ERemoveDirectory(strFullName,Wipe);

								if (MsgCode==DELETE_CANCEL)
								{
									Cancel=true;;
									break;
								}
								else if (MsgCode==DELETE_SKIP)
								{
									//ScTree.SkipDir();
									continue;
								}

								TreeList::DelTreeName(strFullName);
							}
						}
						else
						{
							int AskCode=AskDeleteReadOnly(strFullName,FindData.dwFileAttributes,Wipe);

							if (AskCode==DELETE_CANCEL)
							{
								Cancel=true;
								break;
							}

							if (AskCode==DELETE_YES)
								if (ShellRemoveFile(strFullName,Wipe)==DELETE_CANCEL)
								{
									Cancel=true;
									break;
								}
						}
					}
				}

				if (!Cancel)
				{
					if (FileAttr & FILE_ATTRIBUTE_READONLY)
						apiSetFileAttributes(strSelName,FILE_ATTRIBUTE_NORMAL);

					int DeleteCode;

					// нефига здесь выделываться, а надо учесть, что удаление
					// симлинка в корзину чревато потерей оригинала.
					if (DirSymLink || !Opt.DeleteToRecycleBin || Wipe)
					{
						DeleteCode=ERemoveDirectory(strSelName,Wipe);

						if (DeleteCode==DELETE_CANCEL)
							break;
						else if (DeleteCode==DELETE_SUCCESS)
						{
							TreeList::DelTreeName(strSelName);

							if (UpdateDiz)
								SrcPanel->DeleteDiz(strSelName,strSelShortName);
						}
					}
					else
					{
						DeleteCode=RemoveToRecycleBin(strSelName);

						if (!DeleteCode)
							Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),
							        MSG(MCannotDeleteFolder),strSelName,MSG(MOk));
						else
						{
							TreeList::DelTreeName(strSelName);

							if (UpdateDiz)
								SrcPanel->DeleteDiz(strSelName,strSelShortName);
						}
					}
				}
			}
			else
			{
				int AskCode=AskDeleteReadOnly(strSelName,FileAttr,Wipe);

				if (AskCode==DELETE_CANCEL)
					break;

				if (AskCode==DELETE_YES)
				{
					int DeleteCode=ShellRemoveFile(strSelName,Wipe);

					if (DeleteCode==DELETE_SUCCESS && UpdateDiz)
					{
						SrcPanel->DeleteDiz(strSelName,strSelShortName);
					}

					if (DeleteCode==DELETE_CANCEL)
						break;
				}
			}
		}
	}

	if (UpdateDiz)
		if (DizPresent==(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES))
			SrcPanel->FlushDiz();

	delete DeleteTitle;
done:
	Opt.DeleteToRecycleBin=Opt_DeleteToRecycleBin;
	// Разрешить перерисовку фрейма
	FrameFromLaunched->Unlock();

	if (NeedUpdate)
	{
		ShellUpdatePanels(SrcPanel,NeedSetUpADir);
	}
}
Beispiel #5
0
void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessage)
{
	TPreRedrawFuncGuard preRedrawFuncGuard(PR_ReadFileNamesMsg);
	TaskBar TB(false);

	strOriginalCurDir=strCurDir;

	if (!IsVisible() && !IgnoreVisible)
	{
		UpdateRequired=TRUE;
		UpdateRequiredMode=KeepSelection;
		return;
	}

	UpdateRequired=FALSE;
	AccessTimeUpdateRequired=FALSE;
	DizRead=FALSE;
	FAR_FIND_DATA_EX fdata;
	FileListItem *CurPtr=0,**OldData=0;
	string strCurName, strNextCurName;
	int OldFileCount=0;
	StopFSWatcher();

	if (this!=CtrlObject->Cp()->LeftPanel && this!=CtrlObject->Cp()->RightPanel)
		return;

	string strSaveDir;
	apiGetCurrentDirectory(strSaveDir);
	{
		string strOldCurDir = strCurDir;

		if (!SetCurPath())
		{
			FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте...

			if (!StrCmp(strCurDir, strOldCurDir)) //?? i??
			{
				GetPathRoot(strOldCurDir,strOldCurDir);

				if (!apiIsDiskInDrive(strOldCurDir))
					IfGoHome(strOldCurDir.At(0));

				/* При смене каталога путь не изменился */
			}

			return;
		}
	}
	SortGroupsRead=FALSE;

	if (GetFocus())
		CtrlObject->CmdLine->SetCurDir(strCurDir);

	LastCurFile=-1;
	Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
	AnotherPanel->QViewDelTempName();
	size_t PrevSelFileCount=SelFileCount;
	SelFileCount=0;
	SelFileSize=0;
	TotalFileCount=0;
	TotalFileSize=0;
	CacheSelIndex=-1;
	CacheSelClearIndex=-1;

	if (Opt.ShowPanelFree)
	{
		unsigned __int64 TotalSize,TotalFree;

		if (!apiGetDiskSize(strCurDir,&TotalSize,&TotalFree,&FreeDiskSize))
			FreeDiskSize=0;
	}

	if (FileCount>0)
	{
		strCurName = ListData[CurFile]->strName;

		if (ListData[CurFile]->Selected)
		{
			for (int i=CurFile+1; i < FileCount; i++)
			{
				CurPtr = ListData[i];

				if (!CurPtr->Selected)
				{
					strNextCurName = CurPtr->strName;
					break;
				}
			}
		}
	}

	if (KeepSelection || PrevSelFileCount>0)
	{
		OldData=ListData;
		OldFileCount=FileCount;
	}
	else
		DeleteListData(ListData,FileCount);

	ListData=nullptr;
	int ReadOwners=IsColumnDisplayed(OWNER_COLUMN);
	int ReadNumLinks=IsColumnDisplayed(NUMLINK_COLUMN);
	int ReadNumStreams=IsColumnDisplayed(NUMSTREAMS_COLUMN);
	int ReadStreamsSize=IsColumnDisplayed(STREAMSSIZE_COLUMN);
	string strComputerName;

	if (ReadOwners)
	{
		CurPath2ComputerName(strCurDir, strComputerName);
		// сбросим кэш SID`ов
		SIDCacheFlush();
	}

	SetLastError(ERROR_SUCCESS);
	int AllocatedCount=0;
	FileListItem *NewPtr;
	// сформируем заголовок вне цикла
	wchar_t Title[2048];
	int TitleLength=Min((int)X2-X1-1,(int)(ARRAYSIZE(Title))-1);
	//wmemset(Title,0x0CD,TitleLength); //BUGBUG
	//Title[TitleLength]=0;
	MakeSeparator(TitleLength, Title, 9, nullptr);
	BOOL IsShowTitle=FALSE;
	BOOL NeedHighlight=Opt.Highlight && PanelMode != PLUGIN_PANEL;

	if (!Filter)
		Filter=new FileFilter(this,FFT_PANEL);

	//Рефреш текущему времени для фильтра перед началом операции
	Filter->UpdateCurrentTime();
	CtrlObject->HiFiles->UpdateCurrentTime();
	bool bCurDirRoot = false;
	ParsePath(strCurDir, nullptr, &bCurDirRoot);
	PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot);
	bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC);

	FileCount = 0;
	string strFind = strCurDir;
	AddEndSlash(strFind);
	strFind+=L'*';
	::FindFile Find(strFind, true);
	DWORD FindErrorCode = ERROR_SUCCESS;
	bool UseFilter=Filter->IsEnabledOnPanel();
	bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0;

	DWORD StartTime = GetTickCount();

	while (Find.Get(fdata))
	{
		FindErrorCode = GetLastError();

		if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName)))
		{
			if (FileCount>=AllocatedCount)
			{
				AllocatedCount+=4096;
				FileListItem **pTemp;

				if (!(pTemp=(FileListItem **)xf_realloc(ListData,AllocatedCount*sizeof(*ListData))))
					break;

				ListData=pTemp;
			}

			ListData[FileCount] = new FileListItem;
			ListData[FileCount]->Clear();
			NewPtr=ListData[FileCount];
			NewPtr->FileAttr = fdata.dwFileAttributes;
			NewPtr->CreationTime = fdata.ftCreationTime;
			NewPtr->AccessTime = fdata.ftLastAccessTime;
			NewPtr->WriteTime = fdata.ftLastWriteTime;
			NewPtr->ChangeTime = fdata.ftChangeTime;
			NewPtr->FileSize = fdata.nFileSize;
			NewPtr->AllocationSize = fdata.nAllocationSize;
			NewPtr->strName = fdata.strFileName;
			NewPtr->strShortName = fdata.strAlternateFileName;
			NewPtr->Position=FileCount++;
			NewPtr->NumberOfLinks=1;

			if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			{
				NewPtr->ReparseTag=fdata.dwReserved0; //MSDN
			}
			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				TotalFileSize += NewPtr->FileSize;

				if (ReadNumLinks)
					NewPtr->NumberOfLinks=GetNumberOfLinks(fdata.strFileName);
			}
			else
			{
				NewPtr->AllocationSize = 0;
			}

			NewPtr->SortGroup=DEFAULT_SORT_GROUP;

			if (ReadOwners)
			{
				string strOwner;
				GetFileOwner(strComputerName, NewPtr->strName,strOwner);
				NewPtr->strOwner = strOwner;
			}

			NewPtr->NumberOfStreams=NewPtr->FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1;
			NewPtr->StreamsSize=NewPtr->FileSize;

			if (ReadNumStreams||ReadStreamsSize)
			{
				EnumStreams(TestParentFolderName(fdata.strFileName)?strCurDir:fdata.strFileName,NewPtr->StreamsSize,NewPtr->NumberOfStreams);
			}

			if (ReadCustomData)
				CtrlObject->Plugins->GetCustomData(NewPtr);

			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				TotalFileCount++;

			//memcpy(ListData+FileCount,&NewPtr,sizeof(NewPtr));
//      FileCount++;

			DWORD CurTime = GetTickCount();
			if (CurTime - StartTime > RedrawTimeout)
			{
				StartTime = CurTime;
				if (IsVisible())
				{
					if (!IsShowTitle)
					{
						if (!DrawMessage)
						{
							Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title);
							IsShowTitle=TRUE;
							SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE);
						}
					}

					LangString strReadMsg(MReadingFiles);
					strReadMsg << FileCount;

					if (DrawMessage)
					{
						ReadFileNamesMsg(strReadMsg);
					}
					else
					{
						TruncStr(strReadMsg,TitleLength-2);
						int MsgLength=(int)strReadMsg.GetLength();
						GotoXY(X1+1+(TitleLength-MsgLength-1)/2,Y1);
						FS<<L" "<<strReadMsg<<L" ";
					}
				}

				if (CheckForEsc())
				{
					break;
				}
			}
		}
	}

	if (!(FindErrorCode==ERROR_SUCCESS || FindErrorCode==ERROR_NO_MORE_FILES || FindErrorCode==ERROR_FILE_NOT_FOUND))
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MReadFolderError),MSG(MOk));

	if ((Opt.ShowDotsInRoot || !bCurDirRoot) || (NetRoot && CtrlObject->Plugins->FindPlugin(Opt.KnownIDs.Network))) // NetWork Plugin
	{
		if (FileCount>=AllocatedCount)
		{
			FileListItem **pTemp;

			if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+1)*sizeof(*ListData))))
				ListData=pTemp;
		}

		if (ListData)
		{
			ListData[FileCount] = new FileListItem;

			string TwoDotsOwner;
			if (ReadOwners)
			{
				GetFileOwner(strComputerName,strCurDir,TwoDotsOwner);
			}

			FILETIME TwoDotsTimes[4]={};
			if(apiGetFindDataEx(strCurDir,fdata))
			{
				TwoDotsTimes[0]=fdata.ftCreationTime;
				TwoDotsTimes[1]=fdata.ftLastAccessTime;
				TwoDotsTimes[2]=fdata.ftLastWriteTime;
				TwoDotsTimes[3]=fdata.ftChangeTime;
			}

			AddParentPoint(ListData[FileCount],FileCount,TwoDotsTimes,TwoDotsOwner);

			FileCount++;
		}
	}

	if (IsColumnDisplayed(DIZ_COLUMN))
		ReadDiz();

	if (NeedHighlight)
	{
		CtrlObject->HiFiles->GetHiColor(ListData, FileCount);
	}

	if (AnotherPanel->GetMode()==PLUGIN_PANEL)
	{
		HANDLE hAnotherPlugin=AnotherPanel->GetPluginHandle();
		PluginPanelItem *PanelData=nullptr;
		string strPath;
		size_t PanelCount=0;
		strPath = strCurDir;
		AddEndSlash(strPath);

		if (CtrlObject->Plugins->GetVirtualFindData(hAnotherPlugin,&PanelData,&PanelCount,strPath))
		{
			FileListItem **pTemp;

			if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+PanelCount)*sizeof(*ListData))))
			{
				ListData=pTemp;

				for (size_t i=0; i < PanelCount; i++)
				{
					CurPtr = ListData[FileCount+i];
					PluginPanelItem &pfdata=PanelData[i];
					PluginToFileListItem(&PanelData[i],CurPtr);
					CurPtr->Position=FileCount;
					TotalFileSize += pfdata.FileSize;
					CurPtr->PrevSelected=CurPtr->Selected=0;
					CurPtr->ShowFolderSize=0;
					CurPtr->SortGroup=CtrlObject->HiFiles->GetGroup(CurPtr);

					if (!TestParentFolderName(pfdata.FileName) && !(CurPtr->FileAttr & FILE_ATTRIBUTE_DIRECTORY))
						TotalFileCount++;
				}

				// цветовую боевую раскраску в самом конце, за один раз
				CtrlObject->HiFiles->GetHiColor(&ListData[FileCount],PanelCount);
				FileCount+=static_cast<int>(PanelCount);
			}

			CtrlObject->Plugins->FreeVirtualFindData(hAnotherPlugin,PanelData,PanelCount);
		}
	}

	InitFSWatcher(false);
	CorrectPosition();

	if (KeepSelection || PrevSelFileCount>0)
	{
		MoveSelection(ListData,FileCount,OldData,OldFileCount);
		DeleteListData(OldData,OldFileCount);
	}

	if (SortGroups)
		ReadSortGroups(false);

	if (!KeepSelection && PrevSelFileCount>0)
	{
		SaveSelection();
		ClearSelection();
	}

	SortFileList(FALSE);

	if (CurFile>=FileCount || StrCmpI(ListData[CurFile]->strName,strCurName))
		if (!GoToFile(strCurName) && !strNextCurName.IsEmpty())
			GoToFile(strNextCurName);

	/* $ 13.02.2002 DJ
		SetTitle() - только если мы текущий фрейм!
	*/
	if (CtrlObject->Cp() == FrameManager->GetCurrentFrame())
		SetTitle();

	FarChDir(strSaveDir); //???
}
Beispiel #6
0
void FileList::ReadFileNames(int KeepSelection, int UpdateEvenIfPanelInvisible, int DrawMessage)
{
	SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<FileListPreRedrawItem>());
	SCOPED_ACTION(TaskBar)(false);

	strOriginalCurDir = strCurDir;

	if (!IsVisible() && !UpdateEvenIfPanelInvisible)
	{
		UpdateRequired=TRUE;
		UpdateRequiredMode=KeepSelection;
		return;
	}

	UpdateRequired=FALSE;
	AccessTimeUpdateRequired=FALSE;
	DizRead=FALSE;
	api::FAR_FIND_DATA fdata;
	decltype(ListData) OldData;
	string strCurName, strNextCurName;
	StopFSWatcher();

	if (this!=Global->CtrlObject->Cp()->LeftPanel && this!=Global->CtrlObject->Cp()->RightPanel)
		return;

	string strSaveDir;
	api::GetCurrentDirectory(strSaveDir);
	{
		string strOldCurDir(strCurDir);

		if (!SetCurPath())
		{
			FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте...

			if (strCurDir == strOldCurDir) //?? i??
			{
				GetPathRoot(strOldCurDir,strOldCurDir);

				if (!api::IsDiskInDrive(strOldCurDir))
					IfGoHome(strOldCurDir.front());

				/* При смене каталога путь не изменился */
			}

			return;
		}
	}
	SortGroupsRead=FALSE;

	if (GetFocus())
		Global->CtrlObject->CmdLine->SetCurDir(strCurDir);

	LastCurFile=-1;
	Panel *AnotherPanel=Global->CtrlObject->Cp()->GetAnotherPanel(this);
	AnotherPanel->QViewDelTempName();
	size_t PrevSelFileCount=SelFileCount;
	SelFileCount=0;
	SelFileSize=0;
	TotalFileCount=0;
	TotalFileSize=0;
	CacheSelIndex=-1;
	CacheSelClearIndex=-1;
	FreeDiskSize = -1;
	if (Global->Opt->ShowPanelFree)
	{
		api::GetDiskSize(strCurDir, nullptr, nullptr, &FreeDiskSize);
	}

	if (!ListData.empty())
	{
		strCurName = ListData[CurFile].strName;

		if (ListData[CurFile].Selected && !ReturnCurrentFile)
		{
			for (size_t i=CurFile+1; i < ListData.size(); i++)
			{
				if (!ListData[i].Selected)
				{
					strNextCurName = ListData[i].strName;
					break;
				}
			}
		}
	}

	if (KeepSelection || PrevSelFileCount>0)
	{
		OldData.swap(ListData);
	}
	else
		DeleteListData(ListData);

	DWORD FileSystemFlags = 0;
	string PathRoot;
	GetPathRoot(strCurDir, PathRoot);
	api::GetVolumeInformation(PathRoot, nullptr, nullptr, nullptr, &FileSystemFlags, nullptr);

	ListData.clear();

	bool ReadOwners = IsColumnDisplayed(OWNER_COLUMN);
	bool ReadNumLinks = IsColumnDisplayed(NUMLINK_COLUMN);
	bool ReadNumStreams = IsColumnDisplayed(NUMSTREAMS_COLUMN);
	bool ReadStreamsSize = IsColumnDisplayed(STREAMSSIZE_COLUMN);

	if (!(FileSystemFlags&FILE_SUPPORTS_HARD_LINKS) && IsWindows7OrGreater())
	{
		ReadNumLinks = false;
	}

	if(!(FileSystemFlags&FILE_NAMED_STREAMS))
	{
		ReadNumStreams = false;
		ReadStreamsSize = false;
	}

	string strComputerName;

	if (ReadOwners)
	{
		string strTemp;
		CurPath2ComputerName(strCurDir, strComputerName, strTemp);
	}

	SetLastError(ERROR_SUCCESS);
	// сформируем заголовок вне цикла
	string Title = MakeSeparator(X2-X1-1, 9, nullptr);
	BOOL IsShowTitle=FALSE;
	BOOL NeedHighlight=Global->Opt->Highlight && PanelMode != PLUGIN_PANEL;

	if (!Filter)
		Filter = std::make_unique<FileFilter>(this,FFT_PANEL);

	//Рефреш текущему времени для фильтра перед началом операции
	Filter->UpdateCurrentTime();
	Global->CtrlObject->HiFiles->UpdateCurrentTime();
	bool bCurDirRoot = false;
	ParsePath(strCurDir, nullptr, &bCurDirRoot);
	PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot);
	bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC);

	string strFind(strCurDir);
	AddEndSlash(strFind);
	strFind+=L'*';
	api::FindFile Find(strFind, true);
	DWORD FindErrorCode = ERROR_SUCCESS;
	bool UseFilter=Filter->IsEnabledOnPanel();
	bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0;

	DWORD StartTime = GetTickCount();

	std::all_of(CONST_RANGE(Find, fdata) -> bool
	{
		Global->CatchError();
		FindErrorCode = Global->CaughtError();

		if ((Global->Opt->ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName)))
		{
			if (ListData.size() == ListData.capacity())
				ListData.reserve(ListData.size() + 4096);

			ListData.emplace_back(VALUE_TYPE(ListData)());
			auto& NewItem = ListData.back();

			NewItem.FileAttr = fdata.dwFileAttributes;
			NewItem.CreationTime = fdata.ftCreationTime;
			NewItem.AccessTime = fdata.ftLastAccessTime;
			NewItem.WriteTime = fdata.ftLastWriteTime;
			NewItem.ChangeTime = fdata.ftChangeTime;
			NewItem.FileSize = fdata.nFileSize;
			NewItem.AllocationSize = fdata.nAllocationSize;
			NewItem.strName = fdata.strFileName;
			NewItem.strShortName = fdata.strAlternateFileName;
			NewItem.Position = ListData.size() - 1;
			NewItem.NumberOfLinks=1;

			if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			{
				NewItem.ReparseTag=fdata.dwReserved0; //MSDN
			}
			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				TotalFileSize += NewItem.FileSize;

				if (ReadNumLinks)
					NewItem.NumberOfLinks = GetNumberOfLinks(fdata.strFileName, true);
			}
			else
			{
				NewItem.AllocationSize = 0;
			}

			NewItem.SortGroup=DEFAULT_SORT_GROUP;

			if (ReadOwners)
			{
				string strOwner;
				GetFileOwner(strComputerName, NewItem.strName,strOwner);
				NewItem.strOwner = strOwner;
			}

			NewItem.NumberOfStreams=NewItem.FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1;
			NewItem.StreamsSize=NewItem.FileSize;

			if (ReadNumStreams||ReadStreamsSize)
			{
				EnumStreams(TestParentFolderName(fdata.strFileName)? strCurDir : fdata.strFileName, NewItem.StreamsSize, NewItem.NumberOfStreams);
			}

			if (ReadCustomData)
				NewItem.strCustomData = Global->CtrlObject->Plugins->GetCustomData(NewItem.strName);

			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				TotalFileCount++;

			DWORD CurTime = GetTickCount();
			if (CurTime - StartTime > (DWORD)Global->Opt->RedrawTimeout)
			{
				StartTime = CurTime;
				if (IsVisible())
				{
					if (!IsShowTitle)
					{
						if (!DrawMessage)
						{
							Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title);
							IsShowTitle=TRUE;
							SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE);
						}
					}

					LangString strReadMsg(MReadingFiles);
					strReadMsg << ListData.size();

					if (DrawMessage)
					{
						ReadFileNamesMsg(strReadMsg);
					}
					else
					{
						TruncStr(strReadMsg,static_cast<int>(Title.size())-2);
						int MsgLength=(int)strReadMsg.size();
						GotoXY(X1+1+(static_cast<int>(Title.size())-MsgLength-1)/2,Y1);
						Global->FS << L" "<<strReadMsg<<L" ";
					}
				}

				Global->CtrlObject->Macro.SuspendMacros(true);
				bool check = CheckForEsc();
				Global->CtrlObject->Macro.SuspendMacros(false);
				if (check)
				{
					// break loop
					return false;
				}
			}
		}
		return true;
	});
Beispiel #7
0
void PrintFiles(Panel *SrcPanel)
{
	_ALGO(CleverSysLog clv(L"Alt-F5 (PrintFiles)"));
	string strPrinterName;
	DWORD Needed,Returned;
	int PrinterNumber;
	DWORD FileAttr;
	string strSelName;
	long DirsCount=0;
	int SelCount=SrcPanel->GetSelCount();

	if (!SelCount)
	{
		_ALGO(SysLog(L"Error: !SelCount"));
		return;
	}

	// проверка каталогов
	_ALGO(SysLog(L"Check for FILE_ATTRIBUTE_DIRECTORY"));
	SrcPanel->GetSelName(nullptr,FileAttr);

	while (SrcPanel->GetSelName(&strSelName,FileAttr))
	{
		if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY))
			DirsCount++;
	}

	if (DirsCount==SelCount)
		return;

	PRINTER_INFO *pi = nullptr;

	if (EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,nullptr,PRINTER_INFO_LEVEL,nullptr,0,&Needed,&Returned) || Needed<=0)
		return;

	pi = (PRINTER_INFO *)xf_malloc(Needed);

	if (!EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,nullptr,PRINTER_INFO_LEVEL,(LPBYTE)pi,Needed,&Needed,&Returned))
	{
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotEnumeratePrinters),MSG(MOk));
		xf_free(pi);
		return;
	}

	{
		_ALGO(CleverSysLog clv2(L"Show Menu"));
		string strTitle;
		string strName;

		if (SelCount==1)
		{
			SrcPanel->GetSelName(nullptr,FileAttr);
			SrcPanel->GetSelName(&strName,FileAttr);
			TruncStr(strName,50);
			strSelName=strName;
			InsertQuote(strSelName);
			strTitle.Format(MSG(MPrintTo), strSelName.CPtr());
		}
		else
		{
			_ALGO(SysLog(L"Correct: SelCount-=DirsCount"));
			SelCount-=DirsCount;
			strTitle.Format(MSG(MPrintFilesTo),SelCount);
		}

		VMenu PrinterList(strTitle,nullptr,0,ScrY-4);
		PrinterList.SetFlags(VMENU_WRAPMODE|VMENU_SHOWAMPERSAND);
		PrinterList.SetPosition(-1,-1,0,0);
		AddToPrintersMenu(&PrinterList,pi,Returned);
		PrinterList.Process();
		PrinterNumber=PrinterList.Modal::GetExitCode();

		if (PrinterNumber<0)
		{
			xf_free(pi);
			_ALGO(SysLog(L"ESC"));
			return;
		}

		int nSize = PrinterList.GetUserDataSize();
		wchar_t *PrinterName = strPrinterName.GetBuffer(nSize);
		PrinterList.GetUserData(PrinterName, nSize);
		strPrinterName.ReleaseBuffer();
	}

	HANDLE hPrinter;

	if (!OpenPrinter((wchar_t*)strPrinterName.CPtr(),&hPrinter,nullptr))
	{
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotOpenPrinter),
		        strPrinterName,MSG(MOk));
		xf_free(pi);
		_ALGO(SysLog(L"Error: Cannot Open Printer"));
		return;
	}

	{
		_ALGO(CleverSysLog clv3(L"Print selected Files"));
		//SaveScreen SaveScr;
		TPreRedrawFuncGuard preRedrawFuncGuard(PR_PrintMsg);
		SetCursorType(FALSE,0);
		PR_PrintMsg();
		HANDLE hPlugin=SrcPanel->GetPluginHandle();
		int PluginMode=SrcPanel->GetMode()==PLUGIN_PANEL &&
		               !CtrlObject->Plugins.UseFarCommand(hPlugin,PLUGIN_FARGETFILE);
		SrcPanel->GetSelName(nullptr,FileAttr);

		while (SrcPanel->GetSelName(&strSelName,FileAttr))
		{
			if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY))
				continue;

			int Success=FALSE;
			LPCWSTR FileName = nullptr;
			string strTempDir, strTempName;

			if (PluginMode)
			{
				if (FarMkTempEx(strTempDir))
				{
					apiCreateDirectory(strTempDir,nullptr);
					FileListItem ListItem;

					if (SrcPanel->GetLastSelectedItem(&ListItem))
					{
						PluginPanelItem PanelItem;
						FileList::FileListToPluginItem(&ListItem,&PanelItem);

						if (CtrlObject->Plugins.GetFile(hPlugin,&PanelItem,strTempDir,strTempName,OPM_SILENT))
							FileName = strTempName;
						else
							apiRemoveDirectory(strTempDir);

						FileList::FreePluginPanelItem(&PanelItem);
					}
				}
			}
			else
				FileName = strSelName;

			File SrcFile;
			if(SrcFile.Open(FileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING))
			{
				DOC_INFO_1 di1 = {const_cast<LPWSTR>(FileName)};

				if (StartDocPrinter(hPrinter,1,(LPBYTE)&di1))
				{
					char Buffer[8192];
					DWORD Read,Written;
					Success=TRUE;

					while (SrcFile.Read(Buffer, sizeof(Buffer), Read) && Read > 0)
						if (!WritePrinter(hPrinter,Buffer,Read,&Written))
						{
							Success=FALSE;
							break;
						}

					EndDocPrinter(hPrinter);
				}
				SrcFile.Close();
			}

			if (!strTempName.IsEmpty())
			{
				DeleteFileWithFolder(strTempName);
			}

			if (Success)
				SrcPanel->ClearLastGetSelection();
			else
			{
				if (Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MPrintTitle),MSG(MCannotPrint),
				            strSelName,MSG(MSkip),MSG(MCancel)))
					break;
			}
		}

		ClosePrinter(hPrinter);
	}

	SrcPanel->Redraw();
	xf_free(pi);
}
Beispiel #8
0
void PrintFiles(FileList* SrcPanel)
{
	_ALGO(CleverSysLog clv(L"Alt-F5 (PrintFiles)"));
	string strPrinterName;
	DWORD Needed = 0, Returned;
	DWORD FileAttr;
	string strSelName;
	size_t DirsCount=0;
	size_t SelCount=SrcPanel->GetSelCount();

	if (!SelCount)
	{
		_ALGO(SysLog(L"Error: !SelCount"));
		return;
	}

	// проверка каталогов
	_ALGO(SysLog(L"Check for FILE_ATTRIBUTE_DIRECTORY"));
	SrcPanel->GetSelName(nullptr,FileAttr);

	while (SrcPanel->GetSelName(&strSelName,FileAttr))
	{
		if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY))
			DirsCount++;
	}

	if (DirsCount==SelCount)
		return;

	EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, PRINTER_INFO_LEVEL, nullptr, 0, &Needed, &Returned);

	if (!Needed)
		return;

	block_ptr<PRINTER_INFO> pi(Needed);

	if (!EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,nullptr,PRINTER_INFO_LEVEL,(LPBYTE)pi.get(),Needed,&Needed,&Returned))
	{
		Global->CatchError();
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotEnumeratePrinters),MSG(MOk));
		return;
	}

	{
		_ALGO(CleverSysLog clv2(L"Show Menu"));
		LangString strTitle;
		string strName;

		if (SelCount==1)
		{
			SrcPanel->GetSelName(nullptr,FileAttr);
			SrcPanel->GetSelName(&strName,FileAttr);
			strSelName = TruncStr(strName,50);
			strTitle = MPrintTo;
			strTitle << InsertQuote(strSelName);
		}
		else
		{
			_ALGO(SysLog(L"Correct: SelCount-=DirsCount"));
			SelCount-=DirsCount;
			strTitle = MPrintFilesTo;
			strTitle << SelCount;
		}

		VMenu2 PrinterList(strTitle,nullptr,0,ScrY-4);
		PrinterList.SetFlags(VMENU_WRAPMODE|VMENU_SHOWAMPERSAND);
		PrinterList.SetPosition(-1,-1,0,0);
		AddToPrintersMenu(&PrinterList,pi.get(),Returned);

		if (PrinterList.Run()<0)
		{
			_ALGO(SysLog(L"ESC"));
			return;
		}

		strPrinterName = NullToEmpty(static_cast<const wchar_t*>(PrinterList.GetUserData(nullptr, 0)));
	}

	HANDLE hPrinter;

	if (!OpenPrinter(UNSAFE_CSTR(strPrinterName), &hPrinter,nullptr))
	{
		Global->CatchError();
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotOpenPrinter),
		        strPrinterName.data(),MSG(MOk));
		_ALGO(SysLog(L"Error: Cannot Open Printer"));
		return;
	}

	{
		_ALGO(CleverSysLog clv3(L"Print selected Files"));
		SCOPED_ACTION(SaveScreen);

		auto PR_PrintMsg = [](){ Message(0, 0, MSG(MPrintTitle), MSG(MPreparingForPrinting)); };

		SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<PreRedrawItem>(PR_PrintMsg));
		SetCursorType(false, 0);
		PR_PrintMsg();
		auto hPlugin=SrcPanel->GetPluginHandle();
		int PluginMode=SrcPanel->GetMode()==PLUGIN_PANEL &&
		               !Global->CtrlObject->Plugins->UseFarCommand(hPlugin,PLUGIN_FARGETFILE);
		SrcPanel->GetSelName(nullptr,FileAttr);

		while (SrcPanel->GetSelName(&strSelName,FileAttr))
		{
			if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY))
				continue;

			int Success=FALSE;
			string FileName;
			string strTempDir, strTempName;

			if (PluginMode)
			{
				if (FarMkTempEx(strTempDir))
				{
					api::CreateDirectory(strTempDir,nullptr);
					auto ListItem = SrcPanel->GetLastSelectedItem();
					if (ListItem)
					{
						PluginPanelItem PanelItem;
						FileList::FileListToPluginItem(*ListItem, &PanelItem);

						if (Global->CtrlObject->Plugins->GetFile(hPlugin,&PanelItem,strTempDir,strTempName,OPM_SILENT))
							FileName = strTempName;
						else
							api::RemoveDirectory(strTempDir);

						FreePluginPanelItem(PanelItem);
					}
				}
			}
			else
				FileName = strSelName;

			api::File SrcFile;
			if(SrcFile.Open(FileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING))
			{
				DOC_INFO_1 di1 = {UNSAFE_CSTR(FileName)};

				if (StartDocPrinter(hPrinter,1,(LPBYTE)&di1))
				{
					char Buffer[8192];
					DWORD Read,Written;
					Success=TRUE;

					while (SrcFile.Read(Buffer, sizeof(Buffer), Read) && Read > 0)
						if (!WritePrinter(hPrinter,Buffer,Read,&Written))
						{
							Global->CatchError();
							Success=FALSE;
							break;
						}

					EndDocPrinter(hPrinter);
				}
				SrcFile.Close();
			}

			if (!strTempName.empty())
			{
				DeleteFileWithFolder(strTempName);
			}

			if (Success)
				SrcPanel->ClearLastGetSelection();
			else
			{
				if (Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MPrintTitle),MSG(MCannotPrint),
				            strSelName.data(),MSG(MSkip),MSG(MCancel)))
					break;
			}
		}

		ClosePrinter(hPrinter);
	}

	SrcPanel->Redraw();
}
Beispiel #9
0
ShellDelete::ShellDelete(Panel *SrcPanel,bool Wipe):
	ReadOnlyDeleteMode(-1),
	m_SkipMode(-1),
	SkipWipeMode(-1),
	SkipFoldersMode(-1),
	ProcessedItems(0)
{
	SCOPED_ACTION(ChangePriority)(Global->Opt->DelThreadPriority);
	SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<DelPreRedrawItem>());
	os::FAR_FIND_DATA FindData;
	string strDeleteFilesMsg;
	string strSelName;
	string strSelShortName;
	string strDizName;
	DWORD FileAttr;
	size_t SelCount;
	int UpdateDiz;
	int DizPresent;
	int Ret;
	BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE;
	bool Opt_DeleteToRecycleBin=Global->Opt->DeleteToRecycleBin;
	/*& 31.05.2001 OT Запретить перерисовку текущего окна*/
	auto WindowFromLaunched = Global->WindowManager->GetCurrentWindow();
	WindowFromLaunched->Lock();
	bool DeleteAllFolders=!Global->Opt->Confirm.DeleteFolder;
	UpdateDiz=(Global->Opt->Diz.UpdateMode==DIZ_UPDATE_ALWAYS ||
	           (SrcPanel->IsDizDisplayed() &&
	            Global->Opt->Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED));

	SCOPE_EXIT
	{
		Global->Opt->DeleteToRecycleBin=Opt_DeleteToRecycleBin;
		// Разрешить перерисовку окна
		WindowFromLaunched->Unlock();

		if (NeedUpdate)
		{
			ShellUpdatePanels(SrcPanel,NeedSetUpADir);
		}
	};

	if (!(SelCount=SrcPanel->GetSelCount()))
		return;

	// Удаление в корзину только для  FIXED-дисков
	{
		string strRoot;
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);
		ConvertNameToFull(strSelName, strRoot);
		GetPathRoot(strRoot,strRoot);

		if (Global->Opt->DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED)
			Global->Opt->DeleteToRecycleBin=0;
	}

	if (SelCount==1)
	{
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);

		if (TestParentFolderName(strSelName) || strSelName.empty())
		{
			NeedUpdate=FALSE;
			return;
		}

		strDeleteFilesMsg = strSelName;
		QuoteLeadingSpace(strDeleteFilesMsg);
	}
	else
	{
		// в зависимости от числа ставим нужное окончание
		const wchar_t *Ends;
		FormatString StrItems;
		StrItems << SelCount;
		Ends=MSG(MAskDeleteItemsA);
		size_t LenItems = StrItems.size();

		if (LenItems > 0)
		{
			if ((LenItems >= 2 && StrItems[LenItems-2] == L'1') ||
			        StrItems[LenItems-1] >= L'5' ||
			        StrItems[LenItems-1] == L'0')
				Ends=MSG(MAskDeleteItemsS);
			else if (StrItems[LenItems-1] == L'1')
				Ends=MSG(MAskDeleteItems0);
		}
		strDeleteFilesMsg = LangString(MAskDeleteItems) << SelCount << Ends;
	}

	Ret=1;

	//   Обработка "удаления" линков
	if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) && SelCount==1)
	{
		string strJuncName;
		ConvertNameToFull(strSelName,strJuncName);

		if (GetReparsePointInfo(strJuncName, strJuncName)) // ? SelName ?
		{
			NormalizeSymlinkName(strJuncName);
			string strAskDeleteLink=MSG(MAskDeleteLink);
			os::fs::file_status Status(strJuncName);
			if (os::fs::exists(Status))
			{
				strAskDeleteLink+=L" ";
				strAskDeleteLink += MSG(is_directory(Status)? MAskDeleteLinkFolder : MAskDeleteLinkFile);
			}

			Ret=Message(0,2,MSG(MDeleteLinkTitle),
			            strDeleteFilesMsg.data(),
			            strAskDeleteLink.data(),
			            strJuncName.data(),
						MSG(MDeleteLinkDelete), MSG(MCancel));
			if (Ret)
				return;
		}
	}

	if (Ret && Global->Opt->Confirm.Delete)
	{
		LNGID mTitle = Wipe ? MDeleteWipeTitle : MDeleteTitle;
		LNGID mDText;
		string tText;
		LNGID mDBttn = Wipe ? MDeleteWipe : Global->Opt->DeleteToRecycleBin ? MDeleteRecycle : MDelete;
		bool bHilite = Global->Opt->DelOpt.HighlightSelected;
		int mshow = std::min(std::max((int)Global->Opt->DelOpt.ShowSelected, 1), ScrY/2);
		
		std::vector<string> items;
		items.push_back(strDeleteFilesMsg);

		if (SelCount == 1)
		{
			bool folder = (FileAttr & FILE_ATTRIBUTE_DIRECTORY) != 0;

			if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
				mDText = folder ? MAskWipeFolder : MAskWipeFile;
			else
			{
				if (Global->Opt->DeleteToRecycleBin)
					mDText = folder ? MAskDeleteRecycleFolder : MAskDeleteRecycleFile;
				else
					mDText = folder ? MAskDeleteFolder : MAskDeleteFile;
			}
			if (bHilite)
			{
				string name, sname;
				SrcPanel->GetCurName(name, sname);
				QuoteLeadingSpace(name);
				bHilite = strDeleteFilesMsg != name;
			}
		}
		else
		{
			if (Wipe)
			{
				mDText = MAskWipe;
				mTitle = MDeleteWipeTitle;
			}
			else
				mDText = Global->Opt->DeleteToRecycleBin ? MAskDeleteRecycle : MAskDelete;

			if (mshow > 1)
			{
				tText = MSG(mDText) + string(L" ") + strDeleteFilesMsg;
				items.clear();
				DWORD attr;
				string name;
				SrcPanel->GetSelName(nullptr, attr);

				for (size_t i = 0; i < SelCount; ++i)
				{
					if (i == (size_t)mshow-1 && i+1 < SelCount)
					{
						items.push_back(L"...");
						break;
					}
					SrcPanel->GetSelName(&name, attr);
					QuoteLeadingSpace(name);
					items.push_back(name);
				}
			}
		}

		intptr_t start_hilite = 0, end_hilite = 0;

		DialogBuilder Builder(mTitle, nullptr, [&](Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2) -> intptr_t
		{
			if (bHilite && Msg == DN_CTLCOLORDLGITEM && Param1 >= start_hilite && Param1 <= end_hilite)
			{
				auto Colors = static_cast<FarDialogItemColors*>(Param2);
				Colors->Colors[0] = Colors->Colors[1];
			}
			return Dlg->DefProc(Msg, Param1, Param2);
		});

		if (tText.empty())
			tText = MSG(mDText);

		Builder.AddText(tText.data())->Flags = DIF_CENTERTEXT;

		if (bHilite || (mshow > 1 && SelCount > 1))
			Builder.AddSeparator();

		std::for_each(RANGE(items, i)
		{
			TruncStrFromCenter(i, ScrX+1-6*2);
			auto dx = Builder.AddText(i.data());
			dx->Flags = (SelCount <= 1 || mshow <= 1 ? DIF_CENTERTEXT : 0) | DIF_SHOWAMPERSAND;
			size_t index = Builder.GetLastID();
			end_hilite = index;
			if (!start_hilite)
				start_hilite = index;
		});
Beispiel #10
0
const string FormatStr_Size(__int64 FileSize, __int64 AllocationSize, __int64 StreamsSize, const string& strName,
							DWORD FileAttributes,DWORD ShowFolderSize,DWORD ReparseTag,int ColumnType,
							unsigned __int64 Flags,int Width,const wchar_t *CurDir)
{
	FormatString strResult;

	bool Packed=(ColumnType==PACKED_COLUMN);
	bool Streams=(ColumnType==STREAMSSIZE_COLUMN);

	if (ShowFolderSize==2)
	{
		Width--;
		strResult<<L"~";
	}

	if (!Streams && !Packed && (FileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)) && !ShowFolderSize)
	{
		string strMsg;
		const wchar_t *PtrName=MSG(MListFolder);

		if (TestParentFolderName(strName))
		{
			PtrName=MSG(MListUp);
		}
		else
		{
			if (FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT)
			{
				switch(ReparseTag)
				{
				// 0xA0000003L = Directory Junction or Volume Mount Point
				case IO_REPARSE_TAG_MOUNT_POINT:
					{
						LNGID ID_Msg = MListJunction;
						if (Opt.PanelDetailedJunction)
						{
							string strLinkName=CurDir?CurDir:L"";
							AddEndSlash(strLinkName);
							strLinkName+=PointToName(strName);

							if (GetReparsePointInfo(strLinkName, strLinkName))
							{
								NormalizeSymlinkName(strLinkName);
								bool Root;
								if(ParsePath(strLinkName, nullptr, &Root) == PATH_VOLUMEGUID && Root)
								{
									ID_Msg=MListVolMount;
								}
							}
						}
						PtrName=MSG(ID_Msg);
					}
					break;
				// 0xA000000CL = Directory or File Symbolic Link
				case IO_REPARSE_TAG_SYMLINK:
					PtrName = MSG(MListSymlink);
					break;
				// 0x8000000AL = Distributed File System
				case IO_REPARSE_TAG_DFS:
					PtrName = MSG(MListDFS);
					break;
				// 0x80000012L = Distributed File System Replication
				case IO_REPARSE_TAG_DFSR:
					PtrName = MSG(MListDFSR);
					break;
				// 0xC0000004L = Hierarchical Storage Management
				case IO_REPARSE_TAG_HSM:
					PtrName = MSG(MListHSM);
					break;
				// 0x80000006L = Hierarchical Storage Management2
				case IO_REPARSE_TAG_HSM2:
					PtrName = MSG(MListHSM2);
					break;
				// 0x80000007L = Single Instance Storage
				case IO_REPARSE_TAG_SIS:
					PtrName = MSG(MListSIS);
					break;
				// 0x80000008L = Windows Imaging Format
				case IO_REPARSE_TAG_WIM:
					PtrName = MSG(MListWIM);
					break;
				// 0x80000009L = Cluster Shared Volumes
				case IO_REPARSE_TAG_CSV:
					PtrName = MSG(MListCSV);
					break;
				// 0x????????L = anything else
				default:
					if (Opt.ShowUnknownReparsePoint)
					{
						strMsg = FormatString() << L":" << fmt::Radix(16) << fmt::ExactWidth(8) << fmt::FillChar(L'0') << ReparseTag;
						PtrName = strMsg;
					}
					else
					{
						PtrName=MSG(MListUnknownReparsePoint);
					}
				}
			}
		}

		FormatString strStr;
		if(*PtrName)
		{
			if (StrLength(PtrName) <= Width-2 && MSG(MListBrackets)[0] && MSG(MListBrackets)[1])
			{
				strStr << MSG(MListBrackets)[0] << PtrName << MSG(MListBrackets)[1];
			}
			else
			{
				strStr << PtrName;
			}
		}
		strResult<<fmt::ExactWidth(Width)<<strStr;
	}
	else
	{
		string strOutStr;
		strResult<<FileSizeToStr(strOutStr,Packed?AllocationSize:Streams?StreamsSize:FileSize,Width,Flags).CPtr();
	}

	return strResult;
}