void FavoriteHubsFrame::fillList()
{
	bool old_nosave = m_nosave;
	m_nosave = true;
	
	ctrlHubs.DeleteAllItems();
	
	// sort groups
	TStringList groups(getSortedGroups());
	
	for (size_t i = 0; i < groups.size(); ++i)
	{
		// insert groups
		LVGROUP lg = {0};
		lg.cbSize = sizeof(lg);
		lg.iGroupId = static_cast<int>(i);
		lg.state = LVGS_NORMAL |
#ifdef FLYLINKDC_SUPPORT_WIN_XP
		           (CompatibilityManager::isOsVistaPlus() ? LVGS_COLLAPSIBLE : 0)
#else
		           LVGS_COLLAPSIBLE
#endif
		           ;
		lg.mask = LVGF_GROUPID | LVGF_HEADER | LVGF_STATE | LVGF_ALIGN;
		lg.uAlign = LVGA_HEADER_LEFT;
		
		// Header-title must be unicode (Convert if necessary)
		lg.pszHeader = (LPWSTR)groups[i].c_str();
		lg.cchHeader = static_cast<int>(groups[i].size());
		ctrlHubs.InsertGroup(i, &lg);
	}
	
	{
		// [!] IRainman fix.
		FavoriteManager::LockInstanceHubs lockedInstanceHubs;
		const auto& fl = lockedInstanceHubs.getFavoriteHubs();
		auto cnt = ctrlHubs.GetItemCount();
		for (auto i = fl.cbegin(); i != fl.cend(); ++i)
		{
			const string& group = (*i)->getGroup();
			
			int index = 0;
			if (!group.empty())
			{
				TStringList::const_iterator groupI = find(groups.begin() + 1, groups.end(), Text::toT(group));
				if (groupI != groups.end())
					index = groupI - groups.begin();
			}
			
			addEntry(*i, cnt++, index);
		}
	}
	
	m_nosave = old_nosave;
}
void FavoriteHubsFrame::handleMove(bool up) {
	FavoriteHubEntryList& fh = FavoriteManager::getInstance()->getFavoriteHubs();
	if(fh.size() <= 1)
		return;
	
	StateKeeper keeper(ctrlHubs);
	const FavoriteHubEntryList& selected = keeper.getSelection();

	FavoriteHubEntryList fh_copy = fh;
	if(!up)
		reverse(fh_copy.begin(), fh_copy.end());
	FavoriteHubEntryList moved;
	for(FavoriteHubEntryList::iterator i = fh_copy.begin(); i != fh_copy.end(); ++i) {
		if(find(selected.begin(), selected.end(), *i) == selected.end())
			continue;
		if(find(moved.begin(), moved.end(), *i) != moved.end())
			continue;
		const string& group = (*i)->getGroup();
		for(FavoriteHubEntryList::iterator j = i; ;) {
			if(j == fh_copy.begin()) {
				// couldn't move within the same group; change group.
				TStringList groups(getSortedGroups());
				if(!up)
					reverse(groups.begin(), groups.end());
				TStringIterC ig = find(groups.begin(), groups.end(), Text::toT(group));
				if(ig != groups.begin()) {
					FavoriteHubEntryPtr f = *i;
					f->setGroup(Text::fromT(*(ig - 1)));
					i = fh_copy.erase(i);
					fh_copy.push_back(f);
					moved.push_back(f);
				}
				break;
			}
			if((*--j)->getGroup() == group) {
				swap(*i, *j);
				break;
			}
		}
	}
	if(!up)
		reverse(fh_copy.begin(), fh_copy.end());
	fh = fh_copy;
	FavoriteManager::getInstance()->save();

	fillList();
}
void FavoriteHubsFrame::fillList()
{
	bool old_nosave = nosave;
	nosave = true;

	ctrlHubs.DeleteAllItems(); 
	
	// sort groups
	TStringList groups(getSortedGroups());
	
	for(size_t i = 0; i < groups.size(); ++i) {
		// insert groups
		LVGROUP lg = {0};
		lg.cbSize = sizeof(lg);
		lg.iGroupId = i;
		lg.state = LVGS_NORMAL | (WinUtil::getOsMajor() >= 6 ? LVGS_COLLAPSIBLE : 0);
		lg.mask = LVGF_GROUPID | LVGF_HEADER | LVGF_STATE | LVGF_ALIGN;
		lg.uAlign = LVGA_HEADER_LEFT;

		// Header-title must be unicode (Convert if necessary)
		lg.pszHeader = (LPWSTR)groups[i].c_str();
		lg.cchHeader = groups[i].size();
		ctrlHubs.InsertGroup(i, &lg );
	}

	const FavoriteHubEntryList& fl = FavoriteManager::getInstance()->getFavoriteHubs();
	for(FavoriteHubEntryList::const_iterator i = fl.begin(); i != fl.end(); ++i) {
		const string& group = (*i)->getGroup();

		int index = 0;
		if(!group.empty()) {
			TStringList::const_iterator groupI = find(groups.begin() + 1, groups.end(), Text::toT(group));
			if(groupI != groups.end())
				index = groupI - groups.begin();
		}

		addEntry(*i, ctrlHubs.GetItemCount(), index);
	}

	nosave = old_nosave;
}