Пример #1
0
void RecipeFilter::filter( const QString &s )
{
	//do this to only iterate over children of 'currentCategory'
	Q3ListViewItem * pEndItem = NULL;
	if ( currentCategory ) {
		Q3ListViewItem * pStartItem = currentCategory;
		do {
			if ( pStartItem->nextSibling() )
				pEndItem = pStartItem->nextSibling();
			else
				pStartItem = pStartItem->parent();
		}
		while ( pStartItem && !pEndItem );
	}

	//Re-show everything
	Q3ListViewItemIterator list_it;
	if ( currentCategory )
		list_it = Q3ListViewItemIterator( currentCategory );
	else
		list_it = Q3ListViewItemIterator( listview );
	while ( list_it.current() != pEndItem ) {
		list_it.current() ->setVisible( true );
		list_it++;
	}

	// Only filter if the filter text isn't empty
	if ( !s.isEmpty() ) {
		Q3ListViewItemIterator list_it( listview );
		while ( Q3ListViewItem * it = list_it.current() ) {
			if ( it->rtti() == 1000 )  // Its a recipe
			{
				RecipeListItem * recipe_it = ( RecipeListItem* ) it;

				if ( recipe_it->title().contains( s, Qt::CaseInsensitive ) )
				{
					if ( currentCategory ) {
						if ( isParentOf( currentCategory, recipe_it ) )
							recipe_it->setVisible( true );
						else
							recipe_it->setVisible( false );
					}
					else
						recipe_it->setVisible( true );
				}
				else
					recipe_it->setVisible( false );
			}

			++list_it;
		}
		hideIfEmpty();
	}
}
Пример #2
0
void RecipeFilter::filterCategory( int categoryID )
{
	kDebug() << "I got category :" << categoryID ;

	if ( categoryID == -1 )
		currentCategory = 0;
	else {
		Q3ListViewItemIterator list_it( listview );
		while ( Q3ListViewItem * it = list_it.current() ) {
			if ( it->rtti() == 1001 ) {
				CategoryListItem * cat_it = ( CategoryListItem* ) it;
				if ( cat_it->categoryId() == categoryID ) {
					currentCategory = cat_it;
					break;
				}
			}

			++list_it;
		}
	}

	Q3ListViewItemIterator list_it( listview );
	while ( Q3ListViewItem * it = list_it.current() ) {
		if ( categoryID == -1 )
			it->setVisible( true ); // We're not filtering categories
		else if ( it == currentCategory || isParentOf( it, currentCategory ) || isParentOf( currentCategory, it ) )
			it->setVisible( true );
		else
			it->setVisible( false );

		++list_it;
	}

	if ( currentCategory )
		currentCategory->setOpen( true );
}
Пример #3
0
/// @brief Находит один из минимальных путей в графе @p graph
///        от вершины @p beg_vertex до вершины @p end_vertex.
///
/// Волновой алгоритм поиска одного из минимальных путей:
/// 1. Добавить все вершины графа (кроме начальной вершины пути) в множество непроверенных вершин.
///
/// 2. Создать начальную волну и добавить в нее начальную вершину пути.
///
/// 3. Начальная волна - новая волна. Новой волной будем называть последнюю созданную волну.
///
/// 4. Сформировать следующую волну для новой волны. В нее попадет та вершина,
///    которая является смежной вершине из новой волны и присутствует во множестве непроверенных вершин.
///    Если вершина попала в формируемую волну, то ее надо исключить из множества непроверенных вершин.
///    Созданную волну установим как следующую для новой волны, и после этого созданную волну будем считать новой волной.
///
/// 5. Если новая волна пуста, то значит между вершинами не существует пути.
///    Завершить алгоритм.
///
/// 6. Если в текущей волне есть конечная вершина, то перейти к пункту 7, иначе к пункту 4.
///
/// 7. Сформировать один из минимальных путей, проходя в обратном порядке по списку волн.
///
/// @param s          sc-сессия, при помощи которой будет производиться работа с sc-памятью.
/// @param seg        sc-сегмент, в котором происходит работа алгоритма.
/// @param graph      неориентированный граф, в котором будет находится минимальный путь.
/// @param beg_vertex начальная вершина пути.
/// @param end_vertex конечная вершина пути.
///
/// @return связка отношения "простая цепь*" или 0, если минимальный путь не найден.
///
sc_addr find_min_path(sc_session* s, sc_segment* seg, sc_addr graph, sc_addr beg_vertex, sc_addr end_vertex)
{
	// 1. Добавить все вершины графа (кроме начальной вершины пути) в множество непроверенных вершин.
	//
	sc_addr not_checked_vertexes = s->create_el(seg, SC_N_CONST); // множество непроверенных вершин

	// Итератор по вершинам графа
	//
	sc_iterator *it = s->create_iterator(
		sc_constraint_new(
			CONSTR_3_f_a_a, 
			graph,
			SC_A_CONST|SC_POS,
			0,
			SC_A_CONST|SC_POS,
			graph_theory::vertex_
		), true);

	sc_for_each (it) {
		sc_addr vertex = it->value(2);

		// Не добавляем вершину начала пути в множество непросмотренных вершин.
		//
		if (vertex != beg_vertex)
			sc_set::include_in(s, it->value(2), not_checked_vertexes);
	}

	// 2. Создать начальную волну и добавить в нее начальную вершину пути.
	// 3. Начальная волна - новая волна.
	//
	sc_addr new_wave = s->create_el(seg, SC_N_CONST);
	sc_set::include_in(s, beg_vertex, new_wave);

	// Создаем начало списка волн.
	sc_addr waves_list_head = sc_list::create(s, seg, new_wave);
	sc_addr waves_list_tail = waves_list_head;

	do {
		// 4. Сформировать следующую волну для новой волны.
		//    Установить созданную волну как следующую для новой волны.
		//    Созданная волна - новая волна.
		//
		new_wave = create_wave(s, seg, graph, new_wave, not_checked_vertexes);

		sc_addr waves_list_curr = sc_list::create(s, seg, new_wave);
		sc_list::set_next(s, waves_list_tail, waves_list_curr);

		waves_list_tail = waves_list_curr;

		// 5. Если новая волна пуста, то значит между вершинами не существует пути.
		//
		if (sc_set::is_empty(s, new_wave)) {
			// Очищаем память и завершаем алгоритм.
			//
			erase_waves_list(s, waves_list_head);
			s->erase_el(not_checked_vertexes);
			return 0;
		}

		// 6. Если в текущей волне есть конечная вершина, то перейти к пункту 7, иначе к пункту 4.
		//
	} while (!sc_set::is_in(s, end_vertex, new_wave));

	// Подчистим память...
	//
	s->erase_el(not_checked_vertexes);

	// 7. Сформировать один из минимальных путей, проходя в обратном порядке по списку волн.

	// Сформируем связку отношения "простая цепь*"
	//
	sc_addr route        = s->create_el(seg, SC_N_CONST); // связка отношения "простая цепь*"
	sc_addr route_struct = s->create_el(seg, SC_N_CONST); // ориентированный граф структуры маршрута
	sc_set::include_in(s, route_struct, graph_theory::directed_graph);
	sc_addr route_visit  = s->create_el(seg, SC_N_CONST); // бинарное отношение посещения

	// Добавим все компоненты в связку отношения "простая цепь*".
	//
	sc_tup::add(s, route, N1_, route_struct);
	sc_tup::add(s, route, N2_, graph);
	sc_tup::add(s, route, N3_, route_visit);

	sc_set::include_in(s, route, graph_theory::simple_trail);

	// Добавим в простую цепь посещение начальной вершины.
	//
	sc_addr beg_vertex_visit = add_vertex_visit_to_route(s, route, beg_vertex);

	// Добавим в простую цепь посещение конечной вершины.
	//
	sc_addr end_vertex_visit = add_vertex_visit_to_route(s, route, end_vertex);

	// Пройдем в обратном направлении по списку волн
	// и сформируем структуру маршрута.
	//

	sc_addr curr_vertex = end_vertex;

	// Строим из списка волн маршрут, проходя по этому списку в обратном направлении.
	sc_list::reverse_iterator list_it(s, waves_list_tail), list_end;
	for (++list_it; list_it != list_end; ++list_it) {
		sc_addr curr_wave = *list_it;

		sc_addr edge = find_any_edge(s, graph, curr_vertex, curr_wave);

		// Получаем предыдущую вершину в пути.
		//
		sc_addr prev_vertex = get_other_vertex_incidence_edge(s, edge, curr_vertex); 

		// Добавляем посещение ребра @p edge в путь.
		//
		add_edge_visit_to_route(s, route, edge, prev_vertex, curr_vertex);
		curr_vertex = prev_vertex;
	}

	// Подчистим память...
	//
	erase_waves_list(s, waves_list_head);

	return route;
}