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(); } }
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 ); }
/// @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; }