Example #1
0
bool CTabStack::GetNextTab(const CTabID* pTab, BOOL abForward, /*OUT*/ CTab& rTab)
{
	MSectionLockSimple SC; SC.Lock(mpc_Section);
	CTabID* pNextTab = NULL;

	for (int i = 0; i < mn_Used; i++)
	{
		if (mpp_Stack[i] == pTab)
		{
			if (abForward)
			{
				if ((i + 1) < mn_Used)
					pNextTab = mpp_Stack[i+1];
			}
			else
			{
				if (i > 0)
					pNextTab = mpp_Stack[i-1];
			}
			break;
		}
	}
	rTab.Init(pNextTab);

	SC.Unlock();
	return (pNextTab!=NULL);
}
Example #2
0
bool CTabStack::GetTabByIndex(int anIndex, /*OUT*/ CTab& rTab)
{
	MSectionLockSimple SC; SC.Lock(mpc_Section);

	int iReal = GetVisualToRealIndex(anIndex);
	if (iReal >= 0 && iReal < mn_Used)
	{
		rTab.Init(mpp_Stack[iReal]);
	}
	else
	{
		rTab.Init(NULL);
	}

	SC.Unlock();
	return (rTab.Tab() != NULL);
}
Example #3
0
// Должен вызываться только из CRealConsole!
// Возвращает "true" если были изменения
bool CTabStack::UpdateFarWindow(HANDLE hUpdate, CVirtualConsole* apVCon, LPCWSTR asName, CEFarWindowType anType, int anPID, int anFarWindowID, int anViewEditID, CTab& rActiveTab)
{
	MSectionLockSimple* pUpdateLock = (MSectionLockSimple*)hUpdate;

	// Функция должна вызваться ТОЛЬКО между UpdateBegin & UpdateEnd
	if (mn_UpdatePos < 0 || !pUpdateLock)
	{
		_ASSERTE(mn_UpdatePos>=0);
		_ASSERTE(pUpdateLock!=NULL);
		return false;
	}

	bool bChanged = false;
	CTabID* pTab = NULL;

	mb_FarUpdateMode = true;

	// Теперь - поехали обновлять. Правила такие:
	// 1. Новая вкладка в ФАР может появиться ТОЛЬКО в конце
	// 2. Закрыта может быть любая вкладка
	// 3. панели НЕ должны перебиваться на редактор при запуске "far /e"
	// 4. и вообще, первый таб мог быть добавлен изначально как редактор!

	int i = mn_UpdatePos;
	while (i < mn_Used)
	{
		if (!mpp_Stack[i])
		{
			i++;
			continue;
		}

		if (mpp_Stack[i]->IsEqual(apVCon, asName, anType, anPID, anViewEditID, fwt_TypeMask))
		{
			// OK, таб совпадает
			pTab = mpp_Stack[i];

			// Refresh status and title
			if (pTab->Set(asName, anType, anPID, anFarWindowID, anViewEditID, fwt_UpdateFlags))
				bChanged = true;

			_ASSERTE(pTab->Info.Status == tisValid);

			if (anType & fwt_CurrentFarWnd)
				rActiveTab.Init(pTab);

			mn_UpdatePos = i+1;

			// Закончили
			break;
		}

		// Tab was closed or gone to background
		bChanged = true;
		mpp_Stack[i]->Info.Status = tisPassive;
		i++;
	}

	// Если таб новый
	if (pTab == NULL)
	{
		// это новая вкладка, добавляемая в конец
		pTab = new CTabID(apVCon, asName, anType, anPID, anFarWindowID, anViewEditID);
		_ASSERTE(pTab->RefCount()==1);
		_ASSERTE(mn_Used == i);

		i = AppendInt(pTab, FALSE/*abMoveFirst*/, pUpdateLock);
		_ASSERTE(pTab->RefCount()==2);
		if (anType & fwt_CurrentFarWnd)
			rActiveTab.Init(pTab);
		pTab->Release();

		bChanged = true;
		mn_UpdatePos = i+1;
	}

	_ASSERTE(mn_UpdatePos>=1 && mn_UpdatePos<=mn_Used);

	return bChanged;
}
Example #4
0
bool CTabStack::RefreshFarStatus(DWORD nFarPID, CTab& rActiveTab, int& rnActiveIndex, int& rnActiveCount, bool& rbHasModalTab)
{
	MSectionLockSimple SC; SC.Lock(mpc_Section); // Сразу Exclusive lock
	bool bChanged = false;
	int iCount = 0;
	int iActive = -1;
	int iModal = -1;
	int iFirstAvailable = -1;
	int iFirstPanels = -1;
	DEBUGTEST(int iPanelsCount = 0);
	bool bPanels;

	for (int i = 0; i < mn_Used; i++)
	{
		if (!mpp_Stack[i])
			continue;

		// fwt_Panels всегда должен быть
		bPanels = (mpp_Stack[i]->Type() == fwt_Panels);
		#ifdef _DEBUG
		if (bPanels) iPanelsCount++;
		#endif

		// When returning to Far - mark its editors/viewers as Valid
		if (nFarPID && (mpp_Stack[i]->Info.nPID == nFarPID))
		{
			if (mpp_Stack[i]->Info.Status == tisPassive)
			{
				mpp_Stack[i]->Info.Status = tisValid;
				bChanged = true;
			}
		}
		else if (!bPanels)
		{
			if (mpp_Stack[i]->Info.Status == tisValid)
			{
				mpp_Stack[i]->Info.Status = tisPassive;
				bChanged = true;
			}
		}

		// Find active tabs
		if (mpp_Stack[i]->Info.Status == tisValid)
		{
			iCount++;
			if (mpp_Stack[i]->Info.Type & fwt_CurrentFarWnd)
			{
				_ASSERTE(iActive == -1 && "Only one active tab per console!");
				iActive = i;
			}
			if (mpp_Stack[i]->Info.Type & fwt_ModalFarWnd)
			{
				_ASSERTE((mpp_Stack[i]->Info.Type & fwt_CurrentFarWnd) && "Modal must be current");
				iModal = i;
			}
			if (iFirstAvailable < 0)
			{
				iFirstAvailable = i;
			}
		}
		else if ((iFirstPanels < 0) && bPanels && (mpp_Stack[i]->Info.Status == tisPassive))
		{
			// May be when returning from "far /e ..." to cmd or another std Far instance
			iFirstPanels = i;
		}
	}

	_ASSERTE(iPanelsCount==1);

	// Во время закрытия фара могут быть пертурбации
	if (iActive < 0)
	{
		if (iModal >= 0)
		{
			iActive = iModal;
		}
		else if (iFirstAvailable >= 0)
		{
			iActive = iFirstAvailable;
		}
		else if (iFirstPanels >= 0)
		{
			_ASSERTE(iCount==0);
			iActive = iFirstPanels;
			// There was no one "Active" tab. Mark panels tab as active!
			_ASSERTE(nFarPID == 0); // returning from "far /e ..."?
			_ASSERTE(mpp_Stack[iFirstPanels] != NULL); // Protected with CS, no need to check
			mpp_Stack[iFirstPanels]->Info.Status = tisValid;
			iCount = 1;
		}
		// Check return value
		if (!bChanged)
			bChanged = (iActive >= 0);
	}

	_ASSERTE(iCount>0 && "At least one tab must be available");

	// Во время закрытия фара может возникать...
	if ((iActive >= 0) && !(mpp_Stack[iActive]->Info.Type & fwt_CurrentFarWnd))
	{
		mpp_Stack[iActive]->Info.Type |= fwt_CurrentFarWnd;
	}

	rbHasModalTab = (iModal >= 0);
	rnActiveCount = iCount;
	rActiveTab.Init((iActive >= 0) ? mpp_Stack[iActive] : NULL);
	rnActiveIndex = iActive;

	return bChanged;
}