Exemple #1
0
void CTabBarClass::PrintRecentStack()
{
#ifdef PRINT_RECENT_STACK
	if (!this)
		return;
	wchar_t szDbg[100];
	DEBUGSTRRECENT(L"=== Printing recent tab stack ===\n");
	for (INT_PTR i = 0; i < m_TabStack.size(); i++)
	{
		CTabID* p = m_TabStack[i];
		if (p == mp_DummyTab)
			continue;
		if (!p)
		{
			_ASSERTE(p!=NULL);
			continue;
		}
		_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"%2u: %s", i+1,
			(p->Info.Status == tisPassive) ? L"<passive> " :
			(p->Info.Status == tisEmpty) ? L"<not_init> " :
			(p->Info.Status == tisInvalid) ? L"<invalid> " :
			L"");
		lstrcpyn(szDbg+lstrlen(szDbg), p->GetLabel(), 60);
		wcscat_c(szDbg, L"\n");
		DEBUGSTRRECENT(szDbg);
	}
	DEBUGSTRRECENT(L"===== Recent tab stack done =====\n");
#endif
}
Exemple #2
0
bool CTabStack::SetTabDrawRect(int anIndex, const RECT& rcTab)
{
	bool lbExist = false;
	MSectionLockSimple SC; SC.Lock(mpc_Section);

	int iReal = GetVisualToRealIndex(anIndex);
	if (iReal >= 0 && iReal < mn_Used)
	{
		CTabID* pTab = mpp_Stack[iReal];
		if (pTab)
		{
			if (memcmp(&pTab->DrawInfo.rcTab, &rcTab, sizeof(rcTab)) != 0)
			{
				pTab->ReleaseDrawRegion();
				pTab->DrawInfo.rcTab = rcTab;
			}
			lbExist = true;
		}
		else
		{
			_ASSERTE(pTab!=NULL);
		}
	}
	else
	{
		_ASSERTE(iReal >= 0 && iReal < mn_Used);
	}

	SC.Unlock();
	return lbExist;
}
Exemple #3
0
void CTabStack::ReleaseTabs(BOOL abInvalidOnly /*= TRUE*/)
{
	if (!this || !mpp_Stack || !mn_Used || !mn_MaxCount)
		return;

	MSectionLockSimple SC; SC.Lock(mpc_Section); // Сразу Exclusive lock

	// Идем сзади, т.к. нужно будет сдвигать элементы
	for (int i = (mn_Used - 1); i >= 0; i--)
	{
		if (!mpp_Stack[i])
			continue;
		if (abInvalidOnly)
		{
			if (mpp_Stack[i]->Info.Status == tisValid || mpp_Stack[i]->Info.Status == tisPassive)
				continue;
		}
		CTabID *p = mpp_Stack[i];
		mpp_Stack[i] = NULL;
		#ifdef TAB_REF_PLACE
		p->DelPlace(m_rp);
		#endif
		// Именно Release, т.к. ИД может быть использован в других стеках
		p->Release();

		mn_Used--;

		// Сдвинуть хвост, если есть
		if (abInvalidOnly && (mn_Used > 1) && (i < (mn_Used-1)))
		{
			memmove(mpp_Stack+i, mpp_Stack+i+1, sizeof(CTabID**) * (mn_Used - i));
		}
	}
}
Exemple #4
0
void CTabStack::RecheckPassive()
{
	if (mn_UpdatePos < mn_Used)
	{

		// Освободить все элементы за mn_UpdatePos
		int i = mn_UpdatePos;
		DEBUGTEST(int iPrev = mn_Used);
		while (i < mn_Used)
		{
			CTabID *pTab = mpp_Stack[i];

			if (pTab)
			{
				_ASSERTE(pTab->Info.pVCon!=NULL);
				if (abRConTabs && pTab->Info.pVCon)
				{
					bool bVConValid = false, bPidValid = false, bPassive = false;
					// Only for RCon->tabs.m_Tabs we must to check, if tab is:
					// 'Still Alive'
					// 'Hidden' (Another started Far hides editor/viewer of parent Far)
					// 'Terminated' (Editor/viewer was closed or Far instance terminated)
					CVConGroup::CheckTabValid(pTab, bVConValid, bPidValid, bPassive);

					if (bPidValid)
					{
						if (bPassive)
						{
							// Пока оставить этот таб
							i++;
							continue;
						}
					}
				}

				// If we get here - tab was terminated

				if (abRConTabs)
					pTab->Info.Status = tisInvalid;

				#ifdef TAB_REF_PLACE
				pTab->DelPlace(m_rp);
				#endif

				// Kill this tab
				pTab->Release();
				mpp_Stack[i] = NULL;
			}

			DEBUGTEST(iPrev = mn_Used);
			PRAGMA_ERROR("FAIL. Нужно убрать из стека все NULL-ячейки");
			TabDeleted(pUpdateLock, i);
			_ASSERTE(mn_Used < iPrev);
		}

		mn_Used = mn_UpdatePos;
	}
}
Exemple #5
0
// Возвращает "true" если были изменения в КОЛИЧЕСТВЕ табов (ЗДЕСЬ больше ничего не проверяется)
bool CTabStack::UpdateEnd(HANDLE hUpdate, DWORD anActiveFarPID)
{
	MSectionLockSimple* pUpdateLock = (MSectionLockSimple*)hUpdate;

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

	bool bVConClosed = false;

	if (!mb_FarUpdateMode && (mn_UpdatePos == 0))
	{
		if (!CVConGroup::isVConExists(0))
		{
			bVConClosed = true;
		}
		else
		{
			// Фукнция UpdateFarWindow должна была быть вызвана хотя бы раз!
			//UpdateFarWindow(CVirtualConsole* apVCon, LPCWSTR asName, int anType, int anPID, int anFarWindowID, int anViewEditID, CEFarWindowType anFlags)
			_ASSERTE(mn_UpdatePos>0 || CVConGroup::GetConCount()==0);
			pUpdateLock->Unlock();
			delete pUpdateLock;
			mn_UpdatePos = -1;
			return false;
		}
	}

	bool bChanged = (mn_Used != mn_UpdatePos);

	#if 1
	_ASSERTE(pUpdateLock->isLocked());
	#else
	pUpdateLock->RelockExclusive();
	#endif

	if (mb_FarUpdateMode)
	{
		_ASSERTE(mn_UpdatePos > 0);

		// Все табы ПОСЛЕ последнего добавленного/обновленного - помечаем неактивными
		for (int i = mn_UpdatePos; i < mn_Used; i++)
		{
			CTabID *pTab = mpp_Stack[i];
			if (pTab && (pTab->Info.Status != tisInvalid))
			{
				pTab->Info.Status = tisPassive;
			}
		}

		// Активен Far? ВСЕ tisPassive табы этого Far-а - разрушаем
		if (anActiveFarPID)
		{
			for (int i = 0; i < mn_Used; i++)
			{
				CTabID *pTab = mpp_Stack[i];

				// Проверяем только табы активного фара (пассивные [Far -> Far -> Far] не трогаем)
				if (!pTab || (pTab->Info.nPID != anActiveFarPID))
					continue;
				// Панели и табы с не пассивным статусом - не трогаем
				if ((pTab->Type() == fwt_Panels) || (pTab->Info.Status != tisPassive))
					continue;

				// Таб (редактор/вьювер) был закрыт, разрушаем
				_ASSERTE(pTab->Type()==fwt_Editor || pTab->Type()==fwt_Viewer);

				// Kill this tab
				pTab->Info.Status = tisInvalid;
			}
		}
	}
	else
	{
		// Для самого таббара - весь хвост просто выкинуть из списка, но сами CTabID не разрушать (tisInvalid не ставить)
		for (int i = mn_UpdatePos; i < mn_Used; i++)
		{
			CTabID *pTab = mpp_Stack[i];
			if (pTab)
			{
				if (!CVConGroup::isValid((CVirtualConsole*)pTab->Info.pVCon))
					pTab->Info.Status = tisInvalid;
				#ifdef TAB_REF_PLACE
				pTab->DelPlace(m_rp);
				#endif
				pTab->Release();
				// Remove from list
				mpp_Stack[i] = NULL;

				bChanged = true;
			}
		}
	}

	for (int i = 0; i < mn_Used; i++)
	{
		CTabID *pTab = mpp_Stack[i];

		// Kill all invalid tabs
		if (!pTab || (pTab->Info.Status != tisInvalid))
			continue;

		#ifdef TAB_REF_PLACE
		pTab->DelPlace(m_rp);
		#endif
		pTab->Release();
		// Remove from list
		mpp_Stack[i] = NULL;

		bChanged = true;
	}

	CleanNulls();

	pUpdateLock->Unlock();
	delete pUpdateLock;

	return bChanged;
}
Exemple #6
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;
}