コード例 #1
0
ファイル: panel.cpp プロジェクト: johnd0e/farmanager
string Panel::GetTitle() const
{
	if (m_PanelMode == panel_mode::NORMAL_PANEL)
		return m_ShowShortNames? ConvertNameToShort(m_CurDir) : m_CurDir;

	OpenPanelInfo Info;
	GetOpenPanelInfo(&Info);
	return string(trim(string_view(NullToEmpty(Info.PanelTitle))));
}
コード例 #2
0
ファイル: filetype.cpp プロジェクト: alexlav/conemu
/*
  Используется для запуска внешнего редактора и вьювера
*/
void ProcessExternal(const wchar_t *Command, const wchar_t *Name, const wchar_t *ShortName, bool AlwaysWaitFinish)
{
	string strListName, strAnotherListName;
	string strShortListName, strAnotherShortListName;
	string strFullName, strFullShortName;
	string strExecStr = Command;
	string strFullExecStr = Command;
	{
		int PreserveLFN=SubstFileName(strExecStr,Name,ShortName,&strListName,&strAnotherListName, &strShortListName, &strAnotherShortListName);
		bool ListFileUsed=!strListName.IsEmpty()||!strAnotherListName.IsEmpty()||!strShortListName.IsEmpty()||!strAnotherShortListName.IsEmpty();

		// Снова все "подставлено", теперь проверим условия "if exist"
		if (!ExtractIfExistCommand(strExecStr))
			return;

		PreserveLongName PreserveName(ShortName,PreserveLFN);
		ConvertNameToFull(Name,strFullName);
		ConvertNameToShort(strFullName,strFullShortName);
		//BUGBUGBUGBUGBUGBUG !!! Same ListNames!!!
		SubstFileName(strFullExecStr,strFullName,strFullShortName,&strListName,&strAnotherListName, &strShortListName, &strAnotherShortListName);

		// Снова все "подставлено", теперь проверим условия "if exist"
		if (!ExtractIfExistCommand(strFullExecStr))
			return;

		CtrlObject->ViewHistory->AddToHistory(strFullExecStr,(AlwaysWaitFinish&1)+2);

		if (strExecStr.At(0) != L'@')
			CtrlObject->CmdLine->ExecString(strExecStr,AlwaysWaitFinish, 0, 0, ListFileUsed, true);
		else
		{
			SaveScreen SaveScr;
			CtrlObject->Cp()->LeftPanel->CloseFile();
			CtrlObject->Cp()->RightPanel->CloseFile();
			Execute(strExecStr.CPtr()+1,AlwaysWaitFinish, 0, 0, 0, ListFileUsed);
		}
	}

	if (!strListName.IsEmpty())
		apiDeleteFile(strListName);

	if (!strAnotherListName.IsEmpty())
		apiDeleteFile(strAnotherListName);

	if (!strShortListName.IsEmpty())
		apiDeleteFile(strShortListName);

	if (!strAnotherShortListName.IsEmpty())
		apiDeleteFile(strAnotherShortListName);
}
コード例 #3
0
ファイル: panel.cpp プロジェクト: johnd0e/farmanager
string Panel::CreateFullPathName(string_view const Name, bool const Directory, bool const UNC, bool const ShortNameAsIs) const
{
	auto FullName = FindSlash(Name) == string::npos? ConvertNameToFull(Name) : string(Name);

	if (m_ShowShortNames && ShortNameAsIs)
		FullName = ConvertNameToShort(FullName);

	/* $ 29.01.2001 VVM
	  + По CTRL+ALT+F в командную строку сбрасывается UNC-имя текущего файла. */
	if (UNC)
		FullName = ConvertNameToUNC(FullName);

	// $ 20.10.2000 SVS Сделаем фичу Ctrl-F опциональной!
	if (Global->Opt->PanelCtrlFRule)
	{
		/* $ 13.10.2000 tran
		  по Ctrl-f имя должно отвечать условиям на панели */
		if (m_ViewSettings.Flags&PVS_FOLDERUPPERCASE)
		{
			if (Directory)
			{
				inplace::upper(FullName);
			}
			else
			{
				inplace::upper(FullName, 0, FindLastSlash(FullName));
			}
		}

		if ((m_ViewSettings.Flags&PVS_FILEUPPERTOLOWERCASE) && !Directory)
		{
			const auto pos = FindLastSlash(FullName);
			if (pos != string::npos && !IsCaseMixed(string_view(FullName).substr(pos)))
			{
				inplace::lower(FullName, pos);
			}
		}

		if ((m_ViewSettings.Flags&PVS_FILELOWERCASE) && !Directory)
		{
			const auto pos = FindLastSlash(FullName);
			if (pos != string::npos)
			{
				inplace::lower(FullName, pos);
			}
		}
	}

	return FullName;
}
コード例 #4
0
ファイル: panelmix.cpp プロジェクト: Firebie/FarManager
int _MakePath1(DWORD Key, string &strPathName, const wchar_t *Param2,int ShortNameAsIs)
{
	int RetCode=FALSE;
	int NeedRealName=FALSE;
	strPathName.clear();

	switch (Key)
	{
		case KEY_CTRLALTBRACKET:       // Вставить сетевое (UNC) путь из левой панели
		case KEY_RCTRLRALTBRACKET:
		case KEY_CTRLRALTBRACKET:
		case KEY_RCTRLALTBRACKET:
		case KEY_CTRLALTBACKBRACKET:   // Вставить сетевое (UNC) путь из правой панели
		case KEY_RCTRLRALTBACKBRACKET:
		case KEY_CTRLRALTBACKBRACKET:
		case KEY_RCTRLALTBACKBRACKET:
		case KEY_ALTSHIFTBRACKET:      // Вставить сетевое (UNC) путь из активной панели
		case KEY_RALTSHIFTBRACKET:
		case KEY_ALTSHIFTBACKBRACKET:  // Вставить сетевое (UNC) путь из пассивной панели
		case KEY_RALTSHIFTBACKBRACKET:
			NeedRealName=TRUE;
		case KEY_CTRLBRACKET:          // Вставить путь из левой панели
		case KEY_RCTRLBRACKET:
		case KEY_CTRLBACKBRACKET:      // Вставить путь из правой панели
		case KEY_RCTRLBACKBRACKET:
		case KEY_CTRLSHIFTBRACKET:     // Вставить путь из активной панели
		case KEY_RCTRLSHIFTBRACKET:
		case KEY_CTRLSHIFTBACKBRACKET: // Вставить путь из пассивной панели
		case KEY_RCTRLSHIFTBACKBRACKET:
		case KEY_CTRLSHIFTNUMENTER:    // Текущий файл с пасс.панели
		case KEY_RCTRLSHIFTNUMENTER:
		case KEY_SHIFTNUMENTER:        // Текущий файл с актив.панели
		case KEY_CTRLSHIFTENTER:       // Текущий файл с пасс.панели
		case KEY_RCTRLSHIFTENTER:
		case KEY_SHIFTENTER:           // Текущий файл с актив.панели
		{
			Panel *SrcPanel=nullptr;
			FilePanels *Cp=Global->CtrlObject->Cp();

			switch (Key)
			{
				case KEY_CTRLALTBRACKET:
				case KEY_RCTRLRALTBRACKET:
				case KEY_CTRLRALTBRACKET:
				case KEY_RCTRLALTBRACKET:
				case KEY_CTRLBRACKET:
				case KEY_RCTRLBRACKET:
					SrcPanel=Cp->LeftPanel;
					break;
				case KEY_CTRLALTBACKBRACKET:
				case KEY_RCTRLRALTBACKBRACKET:
				case KEY_CTRLRALTBACKBRACKET:
				case KEY_RCTRLALTBACKBRACKET:
				case KEY_CTRLBACKBRACKET:
				case KEY_RCTRLBACKBRACKET:
					SrcPanel=Cp->RightPanel;
					break;
				case KEY_SHIFTNUMENTER:
				case KEY_SHIFTENTER:
				case KEY_ALTSHIFTBRACKET:
				case KEY_RALTSHIFTBRACKET:
				case KEY_CTRLSHIFTBRACKET:
				case KEY_RCTRLSHIFTBRACKET:
					SrcPanel=Cp->ActivePanel();
					break;
				case KEY_CTRLSHIFTNUMENTER:
				case KEY_RCTRLSHIFTNUMENTER:
				case KEY_CTRLSHIFTENTER:
				case KEY_RCTRLSHIFTENTER:
				case KEY_ALTSHIFTBACKBRACKET:
				case KEY_RALTSHIFTBACKBRACKET:
				case KEY_CTRLSHIFTBACKBRACKET:
				case KEY_RCTRLSHIFTBACKBRACKET:
					SrcPanel=Cp->PassivePanel();
					break;
			}

			if (SrcPanel)
			{
				if (Key == KEY_SHIFTENTER || Key == KEY_CTRLSHIFTENTER || Key == KEY_RCTRLSHIFTENTER || Key == KEY_SHIFTNUMENTER || Key == KEY_CTRLSHIFTNUMENTER || Key == KEY_RCTRLSHIFTNUMENTER)
				{
					string strShortFileName;
					SrcPanel->GetCurName(strPathName,strShortFileName);

					if (SrcPanel->GetShowShortNamesMode()) // учтем короткость имен :-)
						strPathName = strShortFileName;
				}
				else
				{
					if (!(SrcPanel->GetType()==FILE_PANEL || SrcPanel->GetType()==TREE_PANEL))
						return FALSE;

					strPathName = SrcPanel->GetCurDir();

					if (SrcPanel->GetMode()!=PLUGIN_PANEL)
					{
						if (NeedRealName)
							SrcPanel->CreateFullPathName(strPathName, strPathName, FILE_ATTRIBUTE_DIRECTORY, strPathName, TRUE, ShortNameAsIs);

						if (SrcPanel->GetShowShortNamesMode() && ShortNameAsIs)
							ConvertNameToShort(strPathName,strPathName);
					}
					else
					{
						FileList *SrcFilePanel=(FileList *)SrcPanel;
						OpenPanelInfo Info;
						Global->CtrlObject->Plugins->GetOpenPanelInfo(SrcFilePanel->GetPluginHandle(),&Info);
						FileList::AddPluginPrefix(SrcFilePanel,strPathName);
						if (Info.HostFile && *Info.HostFile)
						{
							strPathName += Info.HostFile;
							strPathName += L"/";
						}
						strPathName += NullToEmpty(Info.CurDir);
					}

					AddEndSlash(strPathName);
				}

				if (Global->Opt->QuotedName&QUOTEDNAME_INSERT)
					QuoteSpace(strPathName);

				if (Param2)
					strPathName += Param2;

				RetCode=TRUE;
			}
		}
		break;
	}

	return RetCode;
}
コード例 #5
0
ファイル: fnparce.cpp プロジェクト: alexlav/conemu
static const wchar_t *_SubstFileName(const wchar_t *CurStr,TSubstData *PSubstData,string &strOut)
{
	// рассмотрим переключатели активности/пассивности панели.
	if (!StrCmpN(CurStr,L"!#",2))
	{
		CurStr+=2;
		PSubstData->PassivePanel=TRUE;
		return CurStr;
	}

	if (!StrCmpN(CurStr,L"!^",2))
	{
		CurStr+=2;
		PSubstData->PassivePanel=FALSE;
		return CurStr;
	}

	// !! символ '!'
	if (!StrCmpN(CurStr,L"!!",2) && CurStr[2] != L'?')
	{
		strOut += L"!";
		CurStr+=2;
		return CurStr;
	}

	// !.!      Длинное имя файла с расширением
	if (!StrCmpN(CurStr,L"!.!",3) && CurStr[3] != L'?')
	{
		if (PSubstData->PassivePanel)
			strOut += PSubstData->strAnotherName;
		else
			strOut += PSubstData->Name;

		CurStr+=3;
		return CurStr;
	}

	// !~       Короткое имя файла без расширения
	if (!StrCmpN(CurStr,L"!~",2))
	{
		strOut += PSubstData->PassivePanel ? PSubstData->strAnotherShortNameOnly : PSubstData->strShortNameOnly;
		CurStr+=2;
		return CurStr;
	}

	// !`  Длинное расширение файла без имени
	if (!StrCmpN(CurStr,L"!`",2))
	{
		const wchar_t *Ext;

		if (CurStr[2] == L'~')
		{
			Ext=wcsrchr((PSubstData->PassivePanel ? PSubstData->strAnotherShortName.CPtr():PSubstData->ShortName),L'.');
			CurStr+=3;
		}
		else
		{
			Ext=wcsrchr((PSubstData->PassivePanel ? PSubstData->strAnotherName.CPtr():PSubstData->Name),L'.');
			CurStr+=2;
		}

		if (Ext && *Ext)
			strOut += ++Ext;

		return CurStr;
	}

	// !& !&~  список файлов разделенных пробелом.
	if ((!StrCmpN(CurStr,L"!&~",3) && CurStr[3] != L'?') ||
	        (!StrCmpN(CurStr,L"!&",2) && CurStr[2] != L'?'))
	{
		string strFileNameL, strShortNameL;
		Panel *WPanel=PSubstData->PassivePanel?PSubstData->AnotherPanel:PSubstData->ActivePanel;
		DWORD FileAttrL;
		int ShortN0=FALSE;
		int CntSkip=2;

		if (CurStr[2] == L'~')
		{
			ShortN0=TRUE;
			CntSkip++;
		}

		WPanel->GetSelName(nullptr,FileAttrL);
		int First = TRUE;

		while (WPanel->GetSelName(&strFileNameL,FileAttrL,&strShortNameL))
		{
			if (ShortN0)
				strFileNameL = strShortNameL;
			else // в список все же должно попасть имя в кавычках.
				QuoteSpaceOnly(strFileNameL);

// Вот здесь фиг его знает - нужно/ненужно...
//   если будет нужно - раскомментируем :-)
//          if(FileAttrL & FILE_ATTRIBUTE_DIRECTORY)
//            AddEndSlash(FileNameL);
			// А нужен ли нам пробел в самом начале?
			if (First)
				First = FALSE;
			else
				strOut += L" ";

			strOut += strFileNameL;
		}

		CurStr+=CntSkip;
		return CurStr;
	}

	// !@  Имя файла, содержащего имена помеченных файлов
	// !$!      Имя файла, содержащего короткие имена помеченных файлов
	// Ниже идет совмещение кода для разбора как !@! так и !$!
	//Вообще-то (по исторической справедливости как бы) - в !$! нужно выбрасывать модификаторы Q и A
	// Но нафиг нада:)
	if (!StrCmpN(CurStr,L"!@",2) || !StrCmpN(CurStr,L"!$",2))
	{
		string *pListName;
		string *pAnotherListName;
		bool ShortN0 = FALSE;

		if (CurStr[1] == L'$')
			ShortN0 = TRUE;

		if (ShortN0)
		{
			pListName = PSubstData->pShortListName;
			pAnotherListName = PSubstData->pAnotherShortListName;
		}
		else
		{
			pListName = PSubstData->pListName;
			pAnotherListName = PSubstData->pAnotherListName;
		}

		wchar_t Modifers[32]=L"";
		const wchar_t *Ptr;

		if ((Ptr=wcschr(CurStr+2,L'!')) )
		{
			if (Ptr[1] != L'?')
			{
				xwcsncpy(Modifers,CurStr+2,Min(ARRAYSIZE(Modifers),static_cast<size_t>(Ptr-(CurStr+2)+1)));

				if (pListName)
				{
					if (PSubstData->PassivePanel && (!pAnotherListName->IsEmpty() || PSubstData->AnotherPanel->MakeListFile(*pAnotherListName,ShortN0,Modifers)))
					{
						if (ShortN0)
							ConvertNameToShort(*pAnotherListName, *pAnotherListName);

						strOut += *pAnotherListName;
					}

					if (!PSubstData->PassivePanel && (!pListName->IsEmpty() || PSubstData->ActivePanel->MakeListFile(*pListName,ShortN0,Modifers)))
					{
						if (ShortN0)
							ConvertNameToShort(*pListName,*pListName);

						strOut += *pListName;
					}
				}
				else
				{
					strOut += CurStr;
					strOut += Modifers;
					strOut += L"!";
				}

				CurStr+=Ptr-CurStr+1;
				return CurStr;
			}
		}
	}

	// !-!      Короткое имя файла с расширением
	if (!StrCmpN(CurStr,L"!-!",3) && CurStr[3] != L'?')
	{
		if (PSubstData->PassivePanel)
			strOut += PSubstData->strAnotherShortName;
		else
			strOut += PSubstData->ShortName;

		CurStr+=3;
		return CurStr;
	}

	// !+!      Аналогично !-!, но если длинное имя файла утеряно
	//          после выполнения команды, FAR восстановит его
	if (!StrCmpN(CurStr,L"!+!",3) && CurStr[3] != L'?')
	{
		if (PSubstData->PassivePanel)
			strOut += PSubstData->strAnotherShortName;
		else
			strOut += PSubstData->ShortName;

		CurStr+=3;
		PSubstData->PreserveLFN=TRUE;
		return CurStr;
	}

	// !:       Текущий диск
	if (!StrCmpN(CurStr,L"!:",2))
	{
		string strCurDir;
		string strRootDir;

		if (*PSubstData->Name && PSubstData->Name[1]==L':')
			strCurDir = PSubstData->Name;
		else if (PSubstData->PassivePanel)
			PSubstData->AnotherPanel->GetCurDir(strCurDir);
		else
			strCurDir = PSubstData->strCmdDir;

		GetPathRoot(strCurDir,strRootDir);
		DeleteEndSlash(strRootDir);
		strOut += strRootDir;
		CurStr+=2;
		return CurStr;
	}

	// !\       Текущий путь
	// !/       Короткое имя текущего пути
	// Ниже идет совмещение кода для разбора как !\ так и !/
	if (!StrCmpN(CurStr,L"!\\",2) || !StrCmpN(CurStr,L"!=\\",3) || !StrCmpN(CurStr,L"!/",2) || !StrCmpN(CurStr,L"!=/",3))
	{
		string strCurDir;
		bool ShortN0 = FALSE;
		int RealPath= CurStr[1]==L'='?1:0;

		if (CurStr[1] == L'/' || (RealPath && CurStr[2] == L'/'))
		{
			ShortN0 = TRUE;
		}

		if (PSubstData->PassivePanel)
			PSubstData->AnotherPanel->GetCurDir(strCurDir);
		else
			strCurDir = PSubstData->strCmdDir;

		if (RealPath)
		{
			_MakePath1(PSubstData->PassivePanel?KEY_ALTSHIFTBACKBRACKET:KEY_ALTSHIFTBRACKET,strCurDir,L"",ShortN0);
			Unquote(strCurDir);
		}

		if (ShortN0)
			ConvertNameToShort(strCurDir,strCurDir);

		AddEndSlash(strCurDir);

		CurStr+=2+RealPath;

		if (*CurStr==L'!')
		{
			if (wcspbrk(PSubstData->PassivePanel?PSubstData->strAnotherName.CPtr():PSubstData->Name,L"\\:"))
				strCurDir.Clear();
		}

		strOut +=  strCurDir;
		return CurStr;
	}

	// !?<title>?<init>!
	if (!StrCmpN(CurStr,L"!?",2) && wcschr(CurStr+2,L'!'))
	{
		int j;
		int i = IsReplaceVariable(CurStr);

		if (i == -1)  // if bad format string
		{             // skip 1 char
			j = 1;
		}
		else
		{
			j = i + 1;
		}

		strOut.Append(CurStr, j);
		CurStr += j;
		return CurStr;
	}

	// !        Длинное имя файла без расширения
	if (*CurStr==L'!')
	{
		strOut += PointToName(PSubstData->PassivePanel ? PSubstData->strAnotherNameOnly : PSubstData->strNameOnly);
		CurStr++;
	}

	return CurStr;
}
コード例 #6
0
ファイル: fnparce.cpp プロジェクト: alexlav/conemu
bool Panel::MakeListFile(string &strListFileName,bool ShortNames,const wchar_t *Modifers)
{
	bool Ret=false;

	if (FarMkTempEx(strListFileName))
	{
		File ListFile;
		if (ListFile.Open(strListFileName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,nullptr,CREATE_ALWAYS))
		{
			UINT CodePage=CP_OEMCP;
			LPCVOID Eol="\r\n";
			DWORD EolSize=2;

			if (Modifers && *Modifers)
			{
				if (wcschr(Modifers,L'A')) // ANSI
				{
					CodePage=CP_ACP;
				}
				else
				{
					DWORD Signature=0;
					int SignatureSize=0;

					if (wcschr(Modifers,L'W')) // UTF16LE
					{
						CodePage=CP_UNICODE;
						Signature=SIGN_UNICODE;
						SignatureSize=2;
						Eol=DOS_EOL_fmt;
						EolSize=2*sizeof(WCHAR);
					}
					else
					{
						if (wcschr(Modifers,L'U')) // UTF8
						{
							CodePage=CP_UTF8;
							Signature=SIGN_UTF8;
							SignatureSize=3;
						}
					}

					if (Signature && SignatureSize)
					{
						DWORD NumberOfBytesWritten;
						ListFile.Write(&Signature,SignatureSize, NumberOfBytesWritten);
					}
				}
			}

			string strFileName,strShortName;
			DWORD FileAttr;
			GetSelName(nullptr,FileAttr);

			while (GetSelName(&strFileName,FileAttr,&strShortName))
			{
				if (ShortNames)
					strFileName = strShortName;

				if (Modifers && *Modifers)
				{
					if (wcschr(Modifers,L'F') && PointToName(strFileName) == strFileName.CPtr()) // 'F' - использовать полный путь; //BUGBUG ?
					{
						string strTempFileName=strCurDir;

						if (ShortNames)
							ConvertNameToShort(strTempFileName,strTempFileName);

						AddEndSlash(strTempFileName);
						strTempFileName+=strFileName; //BUGBUG ?
						strFileName=strTempFileName;
					}

					if (wcschr(Modifers,L'Q')) // 'Q' - заключать имена с пробелами в кавычки;
						QuoteSpaceOnly(strFileName);

					if (wcschr(Modifers,L'S')) // 'S' - использовать '/' вместо '\' в путях файлов;
					{
						size_t Len=strFileName.GetLength();
						wchar_t *FileName=strFileName.GetBuffer();

						for (size_t i=0; i<Len; i++)
						{
							if (FileName[i]==L'\\')
							{
								FileName[i]=L'/';
							}
						}

						strFileName.ReleaseBuffer();
					}
				}

				LPCVOID Ptr=nullptr;
				LPSTR Buffer=nullptr;
				DWORD NumberOfBytesToWrite=0,NumberOfBytesWritten=0;

				if (CodePage==CP_UNICODE)
				{
					Ptr=strFileName.CPtr();
					NumberOfBytesToWrite=static_cast<DWORD>(strFileName.GetLength()*sizeof(WCHAR));
				}
				else
				{
					int Size=WideCharToMultiByte(CodePage,0,strFileName,static_cast<int>(strFileName.GetLength()),nullptr,0,nullptr,nullptr);

					if (Size)
					{
						Buffer=static_cast<LPSTR>(xf_malloc(Size));

						if (Buffer)
						{
							NumberOfBytesToWrite=WideCharToMultiByte(CodePage,0,strFileName,static_cast<int>(strFileName.GetLength()),Buffer,Size,nullptr,nullptr);
							Ptr=Buffer;
						}
					}
				}

				BOOL Written=ListFile.Write(Ptr,NumberOfBytesToWrite,NumberOfBytesWritten);

				if (Buffer)
					xf_free(Buffer);

				if (Written && NumberOfBytesWritten==NumberOfBytesToWrite)
				{
					if (ListFile.Write(Eol,EolSize,NumberOfBytesWritten) && NumberOfBytesWritten==EolSize)
					{
						Ret=true;
					}
				}
				else
				{
					Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MCannotCreateListFile),MSG(MCannotCreateListWrite),MSG(MOk));
					apiDeleteFile(strListFileName);
					break;
				}
			}

			ListFile.Close();
		}
		else
		{
			Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MCannotCreateListFile),MSG(MCannotCreateListTemp),MSG(MOk));
		}
	}
	else
	{
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MCannotCreateListFile),MSG(MCannotCreateListTemp),MSG(MOk));
	}

	return Ret;
}
コード例 #7
0
ファイル: arccmd.cpp プロジェクト: CyberShadow/FAR
int ArcCommand::ReplaceVar(char *Command,int &Length)
{
  char Chr=Command[2]&(~0x20);
  if (Command[0]!='%' || Command[1]!='%' || Chr < 'A' || Chr > 'Z')
    return FALSE;
  char SaveStr[MAX_COMMAND_LENGTH],LocalAllFilesMask[NM];
  int QuoteName=0,UseSlash=FALSE,FolderMask=FALSE,FolderName=FALSE;
  int NameOnly=FALSE,PathOnly=FALSE,AnsiCode=FALSE;
  int MaxNamesLength=127;

  int VarLength=3;

  lstrcpy(LocalAllFilesMask,AllFilesMask);

  while (1)
  {
    int BreakScan=FALSE;
    Chr=Command[VarLength];
    if (Command[2]=='F' && Chr >= '0' && Chr <= '9')
    {
      MaxNamesLength=FSF.atoi(&Command[VarLength]);
      while (Chr >= '0' && Chr <= '9')
        Chr=Command[++VarLength];
      continue;
    }
    if (Command[2]=='E' && Chr >= '0' && Chr <= '9')
    {
      MaxAllowedExitCode=FSF.atoi(&Command[VarLength]);
      while (Chr >= '0' && Chr <= '9')
        Chr=Command[++VarLength];
      continue;
    }
    switch(Command[VarLength])
    {
      case 'A':
        AnsiCode=TRUE;
        break;
      case 'Q':
        QuoteName=1;
        break;
      case 'q':
        QuoteName=2;
        break;
      case 'S':
        UseSlash=TRUE;
        break;
      case 'M':
        FolderMask=TRUE;
        break;
      case 'N':
        FolderName=TRUE;
        break;
      case 'W':
        NameOnly=TRUE;
        break;
      case 'P':
        PathOnly=TRUE;
        break;
      case '*':
        lstrcpy(LocalAllFilesMask,"*");
        break;
      default:
        BreakScan=TRUE;
        break;
    }
    if (BreakScan)
      break;
    VarLength++;
  }
  if ((MaxNamesLength-=Length)<=0)
    MaxNamesLength=1;
  if (MaxNamesLength>MAX_COMMAND_LENGTH-512)
    MaxNamesLength=MAX_COMMAND_LENGTH-512;
  if (FolderMask==FALSE && FolderName==FALSE)
    FolderName=TRUE;
  lstrcpy(SaveStr,Command+VarLength);
  switch(Command[2])
  {
    case 'A':
      lstrcpy(Command,ArcName);
      if (AnsiCode)
        OemToChar(Command,Command);
      if (PathOnly)
      {
        char *NamePtr=(char *)FSF.PointToName(Command);
        if (NamePtr!=Command)
          *(NamePtr-1)=0;
        else
          lstrcpy(Command," ");
      }
      FSF.QuoteSpaceOnly(Command);
      break;
    case 'a':
      {
        int Dot=strchr(FSF.PointToName(ArcName),'.')!=NULL;
        ConvertNameToShort(ArcName,Command);
        char *Slash=strrchr(ArcName,'\\');
        if (GetFileAttributes(ArcName)==0xFFFFFFFF && Slash!=NULL && Slash!=ArcName)
        {
          char Path[NM];
          lstrcpy(Path,ArcName);
          Path[Slash-ArcName]=0;
          ConvertNameToShort(Path,Command);
          lstrcat(Command,Slash);
        }
        if (Dot && strchr(FSF.PointToName(Command),'.')==NULL)
          lstrcat(Command,".");
        if (AnsiCode)
          OemToChar(Command,Command);
        if (PathOnly)
        {
          char *NamePtr=(char *)FSF.PointToName(Command);
          if (NamePtr!=Command)
            *(NamePtr-1)=0;
          else
            lstrcpy(Command," ");
        }
      }
      FSF.QuoteSpaceOnly(Command);
      break;
    case 'D':
      *Command=0;
      break;
    case 'E':
      *Command=0;
      break;
    case 'l':
    case 'L':
      if (!MakeListFile(ListFileName,Command[2]=='l',QuoteName,UseSlash,
                        FolderName,NameOnly,PathOnly,FolderMask,
                        LocalAllFilesMask,AnsiCode))
        return -1;
      char QListName[NM+2];
      FSF.QuoteSpaceOnly(lstrcpy(QListName,ListFileName));
      lstrcpy(Command,QListName);
      break;
    case 'P':
      lstrcpy(Command,Password);
      break;
    case 'C':
      if(*CommentFileName) //второй раз сюда не лезем
        break;
      {
        *Command=0;

        HANDLE CommentFile;
        //char CommentFileName[MAX_PATH];
        char Buf[512];
        SECURITY_ATTRIBUTES sa;

        sa.nLength=sizeof(sa);
        sa.lpSecurityDescriptor=NULL;
        sa.bInheritHandle=TRUE;

        if(FSF.MkTemp(CommentFileName, "FAR") &&
          (CommentFile=CreateFile(CommentFileName, GENERIC_WRITE,
                       FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, CREATE_ALWAYS,
                       /*FILE_ATTRIBUTE_TEMPORARY|*//*FILE_FLAG_DELETE_ON_CLOSE*/0, NULL))
                       != INVALID_HANDLE_VALUE)
        {
          DWORD Count;
          if(Info.InputBox(GetMsg(MComment), GetMsg(MInputComment), NULL, "", Buf, sizeof(Buf), NULL, 0))
          //??тут можно и заполнить строку комментарием, но надо знать, файловый
          //?? он или архивный. да и имя файла в архиве тоже надо знать...
          {
            WriteFile(CommentFile, Buf, lstrlen(Buf), &Count, NULL);
            lstrcpy(Command, CommentFileName);
            CloseHandle(CommentFile);
          }
          FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
        }
      }
      break;
    case 'R':
      lstrcpy(Command,RealArcDir);
      if (UseSlash)
      {
        for (int I=0;Command[I];I++)
          if (Command[I]=='\\')
//            Command[I]='//';
/* $ 28.11.2000 AS
*/
            Command[I]='/';
/* AS $*/
      }
      FSF.QuoteSpaceOnly(Command);
      break;
    case 'W':
      lstrcpy(Command,TempPath);
      break;
    case 'f':
    case 'F':
      if (PanelItem!=NULL)
      {
        char CurArcDir[NM];
        lstrcpy(CurArcDir,ArcDir);
        int Length=lstrlen(CurArcDir);
        if (Length>0 && CurArcDir[Length-1]!='\\')
          lstrcat(CurArcDir,"\\");

        char Names[MAX_COMMAND_LENGTH];
        *Names=0;

        if (NameNumber==-1)
          NameNumber=0;

        while (NameNumber<ItemsNumber || Command[2]=='f')
        {
          char Name[NM*2];

          int IncreaseNumber=0,FileAttr;
          if (*NextFileName)
          {
            FSF.sprintf(Name,"%s%s%s",PrefixFileName,CurArcDir,NextFileName);
            *NextFileName=0;
            FileAttr=0;
          }
          else
          {
            int N;
            if (Command[2]=='f' && PrevFileNameNumber!=-1)
              N=PrevFileNameNumber;
            else
            {
              N=NameNumber;
              IncreaseNumber=1;
            }
            if (N>=ItemsNumber)
              break;

            *PrefixFileName=0;
            char *cFileName=PanelItem[N].FindData.cFileName;

            if(PanelItem[N].UserData && (PanelItem[N].Flags & PPIF_USERDATA))
            {
              struct ArcItemUserData *aud=(struct ArcItemUserData*)PanelItem[N].UserData;
              if(aud->SizeStruct == sizeof(struct ArcItemUserData))
              {
                if(aud->Prefix)
                  lstrcpyn(PrefixFileName,aud->Prefix,sizeof(PrefixFileName));
                if(aud->LinkName)
                  cFileName=aud->LinkName;
              }
            }
            // CHECK for BUGS!!
            if(*cFileName == '\\' || *cFileName == '/')
              FSF.sprintf(Name,"%s%s",PrefixFileName,cFileName+1);
            else
              FSF.sprintf(Name,"%s%s%s",PrefixFileName,CurArcDir,cFileName);
            NormalizePath(Name,Name);
            FileAttr=PanelItem[N].FindData.dwFileAttributes;
            PrevFileNameNumber=N;
          }
          if (AnsiCode)
            OemToChar(Name,Name);
          if (NameOnly)
          {
            char NewName[NM];
            lstrcpy(NewName,FSF.PointToName(Name));
            lstrcpy(Name,NewName);
          }
          if (PathOnly)
          {
            char *NamePtr=(char *)FSF.PointToName(Name);
            if (NamePtr!=Name)
              *(NamePtr-1)=0;
            else
              lstrcpy(Name," ");
          }
          if (*Names==0 || (lstrlen(Names)+lstrlen(Name)<MaxNamesLength && Command[2]!='f'))
          {
            NameNumber+=IncreaseNumber;
            if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
            {
              char FolderMaskName[NM];
              //lstrcpy(LocalAllFilesMask,PrefixFileName);
              FSF.sprintf(FolderMaskName,"%s\\%s",Name,LocalAllFilesMask);
              if (PathOnly)
              {
                lstrcpy(FolderMaskName,Name);
                char *NamePtr=(char *)FSF.PointToName(FolderMaskName);
                if (NamePtr!=FolderMaskName)
                  *(NamePtr-1)=0;
                else
                  lstrcpy(FolderMaskName," ");
              }
              if (FolderMask)
              {
                if (FolderName)
                  lstrcpy(NextFileName,FolderMaskName);
                else
                  lstrcpy(Name,FolderMaskName);
              }
            }

            if (QuoteName==1)
              FSF.QuoteSpaceOnly(Name);
            else
              if (QuoteName==2)
                QuoteText(Name);
            if (UseSlash)
              for (int I=0;Name[I];I++)
                if (Name[I]=='\\')
//                  Name[I]='//';
/* $ 28.11.2000 AS
*/
                  Name[I]='/';
/* AS $*/


            if (*Names)
              lstrcat(Names," ");
            lstrcat(Names,Name);
          }
          else
            break;
        }
        lstrcpy(Command,Names);
      }
      else
        *Command=0;
      break;
    default:
      return FALSE;
  }
  Length=lstrlen(Command);
  lstrcat(Command,SaveStr);
  return TRUE;
}
コード例 #8
0
ファイル: panel.cpp プロジェクト: johnd0e/farmanager
bool Panel::MakeListFile(string& ListFileName, bool ShortNames, string_view const Modifers)
{
	uintptr_t CodePage = CP_OEMCP;

	if (!Modifers.empty())
	{
		if (contains(Modifers, L'A')) // ANSI
		{
			CodePage = CP_ACP;
		}
		else if (contains(Modifers, L'U')) // UTF8
		{
			CodePage = CP_UTF8;
		}
		else if (contains(Modifers, L'W')) // UTF16LE
		{
			CodePage = CP_UNICODE;
		}
	}

	const auto& transform = [&](string& strFileName)
	{
		if (!Modifers.empty())
		{
			if (contains(Modifers, L'F') && PointToName(strFileName).size() == strFileName.size()) // 'F' - использовать полный путь; //BUGBUG ?
			{
				strFileName = path::join(ShortNames ? ConvertNameToShort(m_CurDir) : m_CurDir, strFileName); //BUGBUG ?
			}

			if (contains(Modifers, L'Q')) // 'Q' - заключать имена с пробелами в кавычки;
				QuoteSpaceOnly(strFileName);

			if (contains(Modifers, L'S')) // 'S' - использовать '/' вместо '\' в путях файлов;
			{
				ReplaceBackslashToSlash(strFileName);
			}
		}
	};

	try
	{
		ListFileName = MakeTemp();
		if (const auto ListFile = os::fs::file(ListFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS))
		{
			os::fs::filebuf StreamBuffer(ListFile, std::ios::out);
			std::ostream Stream(&StreamBuffer);
			Stream.exceptions(Stream.badbit | Stream.failbit);
			encoding::writer Writer(Stream, CodePage);

			for (const auto& i: enum_selected())
			{
				auto Name = ShortNames? i.AlternateFileName() : i.FileName;

				transform(Name);

				Writer.write(Name);
				Writer.write(L"\r\n"sv);
			}

			Stream.flush();
		}
		else
		{
			throw MAKE_FAR_EXCEPTION(msg(lng::MCannotCreateListTemp));
		}

		return true;
	}
	catch (const far_exception& e)
	{
		os::fs::delete_file(ListFileName);
		Message(MSG_WARNING, e.get_error_state(),
			msg(lng::MError),
			{
				msg(lng::MCannotCreateListFile),
				e.get_message()
			},
			{ lng::MOk });
		return false;
	}
}
コード例 #9
0
ファイル: fnparce.cpp プロジェクト: FarGroup/FarManager
static string_view ProcessMetasymbol(string_view const CurStr, subst_data& SubstData, string& Out)
{
	const auto append_with_escape = [EscapeAmpersands = SubstData.EscapeAmpersands](string& Destination, string_view const Str)
	{
		if (EscapeAmpersands && contains(Str, L"&"sv))
		{
			string Escaped(Str);
			replace(Escaped, L"&"sv, L"&&"sv);
			append(Destination, Escaped);
		}
		else
		{
			append(Destination, Str);
		}
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::passive_panel))
	{
		SubstData.PassivePanel = true;
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::active_panel))
	{
		SubstData.PassivePanel = false;
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::exclamation))
	{
		if (!starts_with(Tail, L'?'))
		{
			Out.push_back(L'!');
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::name_extension))
	{
		if (!starts_with(Tail, L'?'))
		{
			append_with_escape(Out, SubstData.Default().Normal.Name);
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_name))
	{
		append_with_escape(Out, SubstData.Default().Short.NameOnly);
		return Tail;
	}

	const auto GetExtension = [](string_view const Name)
	{
		const auto Extension = PointToExt(Name);
		return Extension.empty()? Extension : Extension.substr(1);
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::short_extension))
	{
		append_with_escape(Out, GetExtension(SubstData.Default().Short.Name));
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::extension))
	{
		append_with_escape(Out, GetExtension(SubstData.Default().Normal.Name));
		return Tail;
	}

	const auto CollectNames = [&SubstData, &append_with_escape](string& Str, auto const Selector)
	{
		append_with_escape(Str, join(select(SubstData.Default().Panel->enum_selected(), Selector), L" "sv));
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::short_list))
	{
		if (!starts_with(Tail, L'?'))
		{
			CollectNames(Out, &os::fs::find_data::AlternateFileName);
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::list))
	{
		if (!starts_with(Tail, L'?'))
		{
			CollectNames(Out, [](const os::fs::find_data& Data)
			{
				return quote_space(Data.FileName);
			});

			return Tail;
		}
	}

	const auto GetListName = [&Out, &append_with_escape](string_view const Tail, subst_data& Data, bool Short)
	{
		const auto ExclPos = Tail.find(L'!');
		if (ExclPos == Tail.npos || starts_with(Tail.substr(ExclPos + 1), L'?'))
			return size_t{};

		const auto Modifiers = Tail.substr(0, ExclPos);

		if (Data.ListNames)
		{
			string Str;
			if (Data.Default().Panel->MakeListFile(Str, Short, Modifiers))
			{
				if (Short)
					Str = ConvertNameToShort(Str);

				append_with_escape(Out, Str);
				Data.ListNames->add(std::move(Str));
			}
		}
		else
		{
			append(Out, L'!', Short? L'$' : L'@', Modifiers, L'!');
		}

		return Modifiers.size() + 1;
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::list_file))
	{
		if (const auto Offset = GetListName(Tail, SubstData, false))
			return string_view(Tail).substr(Offset);
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_list_file))
	{
		if (const auto Offset = GetListName(Tail, SubstData, true))
			return string_view(Tail).substr(Offset);
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_name_extension))
	{
		if (!starts_with(Tail, L'?'))
		{
			append_with_escape(Out, SubstData.Default().Short.Name);
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_name_extension_safe))
	{
		if (!starts_with(Tail, L'?'))
		{
			append_with_escape(Out, SubstData.Default().Short.Name);
			SubstData.PreserveLFN = true;
			return Tail;
		}
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::current_drive))
	{
		const auto CurDir =
			IsAbsolutePath(SubstData.This.Normal.Name)?
				SubstData.This.Normal.Name :
				SubstData.PassivePanel?
					SubstData.Another.Panel->GetCurDir() :
					SubstData.CmdDir;

		auto RootDir = GetPathRoot(CurDir);
		DeleteEndSlash(RootDir);
		append_with_escape(Out, RootDir);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::description))
	{
		Out += SubstData.Default().GetDescription();
		return Tail;
	}

	const auto GetPath = [](string_view const Tail, const subst_data& Data, bool Short, bool Real)
	{
		// TODO: paths on plugin panels are ambiguous

		auto CurDir = Data.PassivePanel? Data.Another.Panel->GetCurDir() : Data.CmdDir;

		if (Real)
			CurDir = ConvertNameToReal(CurDir);

		if (Short)
			CurDir = ConvertNameToShort(CurDir);

		AddEndSlash(CurDir);
		return CurDir;
	};

	if (const auto Tail = tokens::skip(CurStr, tokens::path))
	{
		Out += GetPath(Tail, SubstData, false, false);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::short_path))
	{
		Out += GetPath(Tail, SubstData, true, false);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::real_path))
	{
		Out += GetPath(Tail, SubstData, false, true);
		return Tail;
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::real_short_path))
	{
		Out += GetPath(Tail, SubstData, true, true);
		return Tail;
	}

	// !?<title>?<init>!
	if (const auto Tail = tokens::skip(CurStr, tokens::input))
	{
		auto SkipSize = SkipInputToken(CurStr);
		// if bad format string skip 1 char
		if (!SkipSize)
			SkipSize = 1;

		Out.append(CurStr.data(), SkipSize);
		return CurStr.substr(SkipSize);
	}

	if (const auto Tail = tokens::skip(CurStr, tokens::name))
	{
		append(Out, PointToName(SubstData.Default().Normal.NameOnly));
		return Tail;
	}

	return CurStr;
}