⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 feedview.cpp.svn-base

📁 wince c++ 下 开发的 rss 阅读器源代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:

//
// handlers
//

void CFeedView::OnItemOpen() {
//	OpenOnlineMessage(m_oItems[m_nSelectFirst]->Link, m_oItems[m_nSelectFirst]->SiteItem);
}

void CFeedView::OnItemMarkRead() {
	LOG0(1, "CFeedView::OnItemMarkRead()");

	if (m_nSelectFirst != -1) {
		int i;
		for (i = m_nSelectStart; i <= m_nSelectEnd; i++) {
			MarkItem(i, MESSAGE_READ);
			InvalidateItem(i, FALSE);
		}

		if (SiteItem != NULL) {
			if (SiteItem->Type == CSiteItem::VFolder && SiteItem->FlagMask == MESSAGE_READ_STATE) {
				// delete items
				for (i = m_nSelectStart; i <= m_nSelectEnd; i++)
					m_oItems.RemoveAt(m_nSelectStart);
				AdjustViewTop();
				Invalidate(FALSE);
			}
			else if (SiteItem->Type != CSiteItem::VFolder && Config.HideReadItems) {
				// delete items
				for (i = m_nSelectStart; i <= m_nSelectEnd; i++)
					m_oItems.RemoveAt(m_nSelectStart);
				AdjustViewTop();
				Invalidate(FALSE);
			}
		}

		DeselectAllItems();
		SortItems();
		UpdateScrollBars();

		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
		frame->UpdateTopBar();
	}
}

void CFeedView::OnItemMarkUnread() {
	LOG0(1, "CFeedView::OnItemMarkUnread()");

	if (m_nSelectFirst != -1) {
		for (int i = m_nSelectStart; i <= m_nSelectEnd; i++) {
			MarkItem(i, MESSAGE_UNREAD);
			InvalidateItem(i, FALSE);
		}
		DeselectAllItems();
		SortItems();

		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
		frame->UpdateTopBar();
	}
}

void CFeedView::OnItemMarkNew() {
	LOG0(1, "CFeedView::OnItemMarkNew()");

	if (m_nSelectFirst != -1) {
		for (int i = m_nSelectStart; i <= m_nSelectEnd; i++) {
			MarkItem(i, MESSAGE_NEW);
			InvalidateItem(i, FALSE);
		}
		DeselectAllItems();
		SortItems();

		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
		frame->UpdateTopBar();
	}
}

void CFeedView::OnItemFlag() {
	LOG0(1, "CFeedView::OnItemFlag()");

	if (m_nSelectFirst != -1) {
		if (SiteItem != NULL) {
			if (GetItem(m_nSelectFirst)->IsFlagged())
				for (int i = m_nSelectStart; i <= m_nSelectEnd; i++)
					UnflagItem(i);
			else
				for (int i = m_nSelectStart; i <= m_nSelectEnd; i++)
					FlagItem(i);
		}
		DeselectAllItems();

		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
		frame->UpdateTopBar();
	}
}

void CFeedView::OnUpdateItemFlag(CCmdUI *pCmdUI) {
	pCmdUI->SetCheck(GetItem(m_nSelectFirst)->IsFlagged());
}

void CFeedView::OnSelectAll() {
	LOG0(1, "CFeedView::SelectAll()");

	SelectAll();
}

void CFeedView::OnItemDelete() {
	LOG0(1, "CFeedView::OnItemDelete()");

	if (m_nSelectFirst != -1) {
		for (int i = m_nSelectStart; i <= m_nSelectEnd; i++) {
			CFeedItem *fi = GetItem(i);
			fi->SetFlags(MESSAGE_DELETED, MESSAGE_DELETED);
		}

		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();

		// delete from view
		int cnt = m_nSelectEnd - m_nSelectStart + 1;
		m_oItems.RemoveAt(m_nSelectStart, cnt);

		DeselectAllItems();
		SortItems();
		UpdateScrollBars();

		frame->UpdateTopBar();
	}
}

void CFeedView::OnUpdateItemSelected(CCmdUI *pCmdUI) {
	pCmdUI->Enable(m_nSelectFirst != -1);
}

//
//
//

int CFeedView::MoveToNextItem() {
	LOG0(3, "CFeedView::MoveToNextItem()");

	if (m_nSelectFirst < m_oItems.GetSize() - 1) {
		m_nSelectFirst++;
		m_nSelectEnd = m_nSelectStart = m_nSelectFirst;

		// FIXME
		int y;
		if (m_nSelectFirst > 0) y = m_oItemHeight[m_nSelectFirst - 1];
		else y = 0;

		if (y < m_nViewTop)
			m_nViewTop = y;
		else if (m_oItemHeight[m_nSelectFirst] > m_nViewTop + m_nClientHeight)
			m_nViewTop = m_oItemHeight[m_nSelectFirst] - m_nClientHeight;
		AdjustViewTop();

		UpdateScrollBars();
		Invalidate(FALSE);
	}

	return m_nSelectFirst;
}

int CFeedView::MoveToPrevItem() {
	LOG0(3, "CFeedView::MoveToPrevItem()");

	if (m_nSelectFirst > 0) {
		m_nSelectFirst--;
		m_nSelectEnd = m_nSelectStart = m_nSelectFirst;

		// FIXME
		int y;
		if (m_nSelectFirst > 0) y = m_oItemHeight[m_nSelectFirst - 1];
		else y = 0;

		if (y < m_nViewTop)
			m_nViewTop = y;
		else if (m_oItemHeight[m_nSelectFirst] > m_nViewTop + m_nClientHeight)
			m_nViewTop = m_oItemHeight[m_nSelectFirst] - m_nClientHeight;
		AdjustViewTop();

		UpdateScrollBars();
		Invalidate(FALSE);
	}

	return m_nSelectFirst;
}

int CFeedView::MoveToNextChannel() {
	LOG0(3, "CFeedView::MoveToNextChannel()");

	int oldSiteIdx = Config.ActSiteIdx;
	if (Config.ActSiteIdx < SiteList.GetCount() - 1)
		Config.ActSiteIdx++;
	else if (Config.WrapAround)
		Config.ActSiteIdx = 0;

	if (oldSiteIdx != Config.ActSiteIdx) {
		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
		frame->SelectSite(Config.ActSiteIdx);
	}

	return Config.ActSiteIdx;
}

int CFeedView::MoveToPrevChannel() {
	LOG0(3, "CFeedView::MoveToPrevChannel()");

	int oldSiteIdx = Config.ActSiteIdx;
	if (Config.ActSiteIdx > 0)
		Config.ActSiteIdx--;
	else  if (Config.WrapAround)
		Config.ActSiteIdx = SiteList.GetCount() - 1;

	if (oldSiteIdx != Config.ActSiteIdx) {
		CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
		frame->SelectSite(Config.ActSiteIdx);
	}

	return Config.ActSiteIdx;
}

void CFeedView::OpenItem(CFeedItem *fi) {
	LOG1(3, "CFeedView::OpenItem(%p)", fi);

	CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();

	CSiteItem *si = fi->SiteItem;

	// enclosure bar
	frame->SwitchView(CMainFrame::ArticleView);

	frame->m_wndArticleView.SetFeedItem(fi);
	frame->m_wndArticleView.CreateMenu(frame->m_hwndCmdBar);
	frame->SetupEnclosureBar(fi);

	// setup controls
	frame->SetupBanner(fi, m_nSelectFirst + 1, m_oItems.GetSize());
	frame->m_wndArticleView.ShowArticle();
	frame->UpdateTopBar();

	if (si->Feed != NULL) {
		for (int i = 0; i < si->Feed->GetItemCount(); i++) {
			if (si->Feed->GetItem(i) == fi) {
				Config.ActFeedItem = i;
				break;
			}
		}
	}
}

void CFeedView::OpenItem(int item) {
	LOG1(3, "CFeedView::OpenItem(%d)", item);

	if (item < 0 || item >= m_oItems.GetSize())
		return;

	m_nSelectFirst = m_nSelectStart = m_nSelectEnd = item;

	OpenItem(m_oItems.GetAt(item));
	MarkItem(item, MESSAGE_READ);
}

void CFeedView::FlagItem(int item) {
	LOG1(3, "CFeedView::FlagItem(%d)", item);

	CFeedItem *fi = m_oItems.GetAt(item);
	fi->SetFlags(MESSAGE_FLAG, MESSAGE_FLAG);

	CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
	frame->SyncItem(fi);
}

void CFeedView::UnflagItem(int item) {
	LOG1(3, "CFeedView::UnflagItem(%d)", item);

	CFeedItem *fi = m_oItems.GetAt(item);
	fi->SetFlags(0, MESSAGE_FLAG);
	CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
	frame->SyncItem(fi);
}

void CFeedView::OnCopyUrl() {
	LOG0(3, "CFeedView::OnCopyUrl()");

	if (m_nSelectFirst != -1) {
		CString links;
		for (int i = m_nSelectStart; i <= m_nSelectEnd; i++) {
			CFeedItem *fi = m_oItems.GetAt(i);
			if (fi != NULL) {
				if (i > m_nSelectStart)
					links += _T("\n");
				links += fi->Link;
			}
		}

		if (!links.IsEmpty())
			CopyTextToClipboard(GetSafeHwnd(), links);

		DeselectAllItems();
	}
}


void CFeedView::OnSendByEmail() {
	LOG0(3, "CFeedView::OnSendByEmail()");

	if (m_nSelectFirst != -1) {
		CString links;
		for (int i = m_nSelectStart; i <= m_nSelectEnd; i++) {
			CFeedItem *fi = m_oItems.GetAt(i);
			if (fi != NULL) {
				if (i > m_nSelectStart)
					links += _T("\n");
				links += fi->Link;
			}
		}

		if (!links.IsEmpty())
			SendByEmail(links);

		DeselectAllItems();
	}
}

// Sort ////

int CompareFeedItemDate(CFeedItem *fi1, CFeedItem *fi2) {
	FILETIME ft1, ft2;
	SystemTimeToLinearDate(&fi1->Date, &ft1);
	SystemTimeToLinearDate(&fi2->Date, &ft2);
	return CompareFileTime(&ft1, &ft2);
}

int CompareFeedItemFlag(CFeedItem *fi1, CFeedItem *fi2) {
	return ((int) fi1->GetReadState() - (int) fi2->GetReadState());
}

int CompareFlagsAsc(const void *arg1, const void *arg2) {
	CFeedItem *fi1 = (*(CFeedItem **) arg1);
	CFeedItem *fi2 = (*(CFeedItem **) arg2);
	return CompareFeedItemFlag(fi1, fi2);
}

int CompareFlagsDesc(const void *arg1, const void *arg2) {
	CFeedItem *fi1 = (*(CFeedItem **) arg1);
	CFeedItem *fi2 = (*(CFeedItem **) arg2);
	return CompareFeedItemFlag(fi2, fi1);
}

int CompareDateAsc(const void *arg1, const void *arg2) {
	CFeedItem *fi1 = (*(CFeedItem **) arg1);
	CFeedItem *fi2 = (*(CFeedItem **) arg2);
	return CompareFeedItemDate(fi1, fi2);
}

int CompareDateDesc(const void *arg1, const void *arg2) {
	CFeedItem *fi1 = (*(CFeedItem **) arg1);
	CFeedItem *fi2 = (*(CFeedItem **) arg2);
	return CompareFeedItemDate(fi2, fi1);
}

int CompareVFolder(const void *arg1, const void *arg2) {
	CFeedItem *fi1 = (*(CFeedItem **) arg1);
	CFeedItem *fi2 = (*(CFeedItem **) arg2);

	if (fi1->SiteItem == fi2->SiteItem) {
		switch (fi1->SiteItem->Sort.Item) {
			case CSortInfo::Date:
				if (fi1->SiteItem->Sort.Type == CSortInfo::Ascending) return CompareFeedItemDate(fi1, fi2);
				else return CompareFeedItemDate(fi2, fi1);

			case CSortInfo::Read:
				if (fi1->SiteItem->Sort.Type == CSortInfo::Ascending) return CompareFeedItemFlag(fi1, fi2);
				else return CompareFeedItemFlag(fi2, fi1);
		}
	}
	else {
		return fi1->SiteItem - fi2->SiteItem;
	}

	return CompareFeedItemDate(fi2, fi1);
}

void CFeedView::Sort(int (__cdecl *compare)(const void *elem1, const void *elem2)) {
	int count = GetItemCount();
	int i;

	CFeedItem **items = new CFeedItem *[count];
	for (i = 0; i < count; i++)
		items[i] = m_oItems[i];

	qsort((void *) items, count, sizeof(CFeedItem *), compare);

	for (i = 0; i < count; i++)
		m_oItems.SetAt(i, items[i]);
//	UpdateItemHeights();

	delete [] items;
}

void CFeedView::SortItems() {
	LOG0(3, "CFeedView::SortItems()");

	if (SiteItem == NULL)
		return;				// no sorting if we dont know how to sort

	if (SiteItem->Type == CSiteItem::VFolder && Config.GroupByFeed) {
		Sort(CompareVFolder);
	}
	else {
		switch (SiteItem->Sort.Item) {
			case CSortInfo::Date:
				if (SiteItem->Sort.Type == CSortInfo::Ascending) Sort(CompareDateAsc);
				else Sort(CompareDateDesc);
				break;

			case CSortInfo::Read:
				if (SiteItem->Sort.Type == CSortInfo::Ascending) Sort(CompareFlagsAsc);
				else Sort(CompareFlagsDesc);
				break;
		}
	}

	UpdateItemHeights();
}

void CFeedView::OnSortAscending() {
	LOG0(3, "CFeedView::SortAscending()");

	if (SiteItem == NULL)
		return;

	if (SiteItem->Sort.Type != CSortInfo::Ascending) {
		SiteItem->Sort.Type = CSortInfo::Ascending;
		DeselectAllItems();
		SortItems();
	}
}

void CFeedView::OnSortDescending() {
	LOG0(3, "CFeedView::SortDescending()");

	if (SiteItem == NULL)
		return;

	if (SiteItem->Sort.Type != CSortInfo::Descending) {
		SiteItem->Sort.Type = CSortInfo::Descending;
		DeselectAllItems();
		SortItems();
	}
}

void CFeedView::InsertItems(CSiteItem *si) {
	SetRedraw(FALSE);
	DeleteAllItems();
	SiteItem = si;

	CFeed *feed = si->Feed;
	if (feed != NULL) {
		feed->Lock();
		if (si->Type == CSiteItem::Site) {
			for (int i = 0, j = 0; i < feed->GetItemCount(); i++) {
				CFeedItem *item = feed->GetItem(i);
				if (!Config.HideReadItems || !item->IsRead())
					if (InsertItem(j, item))
						j++;
			}
		}
		else if (si->Type == CSiteItem::VFolder) {
			for (int i = 0, j = 0; i < feed->GetItemCount(); i++) {
				CFeedItem *item = feed->GetItem(i);
				if ((item->GetFlags() & si->FlagMask) != 0)
					if (InsertItem(j, item))
						j++;
			}
		}
		feed->Unlock();
	}
	SortItems();
	UpdateScrollBars();

	SetRedraw(TRUE);
	Invalidate();
}

void CFeedView::OnViewHideReadItems() {
	Config.HideReadItems = !Config.HideReadItems;
	Config.SaveUI();

	InsertItems(SiteItem);
	UpdateScrollBars();
	UpdateItemHeights();
}

void CFeedView::OnUpdateViewHideReadItems(CCmdUI *pCmdUI) {
	pCmdUI->SetCheck(Config.HideReadItems);
}

int CFeedView::CalcItemHeight(int idx) {
	if (m_bWrapTitles) {
		CDC *pDC = GetDC();

		CRect rc(0, 0, m_nClientWidth, m_nClientHeight);
		rc.DeflateRect(SCALEX(LEFT_SKIP), SCALEY(PADDING_TOP), SCALEX(PADDING_RIGHT), SCALEY(PADDING_BOTTOM));
		int wd = rc.Width();

		CString strTitle = m_oItems[idx]->Title;
		ReplaceHTMLEntities(strTitle);

		CFont *pOldFont = pDC->SelectObject(&m_fntBold);
		pDC->DrawText(strTitle, &rc, DT_LEFT | DT_TOP | DT_NOPREFIX | DT_CALCRECT | DT_WORDBREAK);
		pDC->SelectObject(pOldFont);
		ReleaseDC(pDC);

		return rc.Height() + SCALEY(DATE_HEIGHT);
	}
	else
		return SCALEY(Appearance.FeedViewFontCfg.Size + ITEM_MARGIN);
}

void CFeedView::UpdateItemHeights() {
	CRect rc;
	GetClientRect(rc);
	m_nClientWidth = rc.Width();

	m_nTotalHeight = 0;
	bool refresh = false;
	for (int i = 0; i < m_oItems.GetSize(); i++) {
		m_nTotalHeight += CalcItemHeight(i);
		if (m_nTotalHeight > m_nClientHeight) {
			m_nClientWidth -= ::GetSystemMetrics(SM_CXVSCROLL);
			refresh = true;
			break;
		}
		m_oItemHeight[i] = m_nTotalHeight;
	}

	if (refresh) {
		m_nTotalHeight = 0;
		for (int i = 0; i < m_oItems.GetSize(); i++) {
			m_nTotalHeight += CalcItemHeight(i);
			m_oItemHeight[i] = m_nTotalHeight;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -