/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2011, Tomasz Sowa * All rights reserved. * */ #include #include "groups.h" #include "core/log.h" namespace GroupItem { Space * Groups::GetSpace() { return &space; } void Groups::Reindex() { set_index.clear(); group_index_tab.clear(); size_t seti = 0; while( seti < space.spaces.size() ) { const std::wstring & name = space.spaces[seti]->name; if( set_index.find(name) == set_index.end() ) { set_index[name] = seti; group_index_tab.push_back(GroupIndex()); ReindexGroups(group_index_tab.back(), *space.spaces[seti]); seti += 1; } else { slog << logerror << "set: " << name << " already defined (skipping)" << logend; space.spaces.erase(space.spaces.begin() + seti); } } } void Groups::ReindexGroups(GroupIndex & group_index, Space & set) { size_t i, v; // loop through all groups in the set for( i=0 ; i < set.spaces.size() ; ++i ) { Space & group = *set.spaces[i]; const std::wstring & key = group.Text(L"key", L"value"); // loop through all values in the group for(v=0 ; vtable.find(key); if( vali != group.spaces[v]->table.end() && vali->second.size() == 1 ) { GroupIndex::iterator g = group_index.find(vali->second[0]); if( g == group_index.end() ) { group_index[vali->second[0]] = i; v += 1; } else { slog << logwarning << "set: " << set.name << " has a group with a duplicated value: " << vali->second[0] << " (skipping)" << logend; group.spaces.erase(group.spaces.begin() + v); } } else { slog << logwarning << "set: " << set.name << " has a group without a value (skipping)" << logend; group.spaces.erase(group.spaces.begin() + v); } } SortValues(group); } } void Groups::SortValues(Space & group) { sort_by = group.Text(L"sort_by"); sort_asc = (group.Text(L"sort_asc", L"true") == L"true"); if( !sort_by.empty() ) { group.ListText(L"sort", sort_value); std::sort(group.spaces.begin(), group.spaces.end(), SortFunHelper(this)); } } bool Groups::SortFunHelper::operator()(Space * sp1, Space * sp2) { const std::wstring & val1 = sp1->Text(groups->sort_by, L""); const std::wstring & val2 = sp2->Text(groups->sort_by, L""); if( groups->sort_asc ) return SortValue(val1) < SortValue(val2); else return SortValue(val1) > SortValue(val2); } size_t Groups::SortFunHelper::SortValue(const std::wstring & val) { for(size_t i=0 ; isort_value.size() ; ++i) if( val == groups->sort_value[i] ) return i; return std::numeric_limits::max(); } bool Groups::Find(const std::wstring & set, const std::wstring & value, size_t & seti, size_t & groupi) { SetIndex::iterator i = set_index.find(set); if( i != set_index.end() ) { if( i->second < group_index_tab.size() ) { GroupIndex::iterator viter = group_index_tab[i->second].find(value); if( viter != group_index_tab[i->second].end() ) { seti = i->second; groupi = viter->second; return true; } } } return false; } const std::wstring & Groups::GetOption(size_t seti, size_t groupi, size_t valuei, const wchar_t * option) { if( seti < space.spaces.size() ) { Space & groups = *space.spaces[seti]; if( groupi < groups.spaces.size() ) { Space & value = *groups.spaces[groupi]; if( valuei < value.spaces.size() ) return value.spaces[valuei]->Text(option); } } return empty_str; } const std::wstring & Groups::GetOption(size_t seti, size_t groupi, size_t valuei, const std::wstring & option) { return GetOption(seti, groupi, valuei, option.c_str()); } size_t Groups::Size(size_t seti, size_t groupi) { if( seti < space.spaces.size() ) { Space & groups = *space.spaces[seti]; if( groupi < groups.spaces.size() ) return groups.spaces[groupi]->spaces.size(); } return 0; } void Groups::Clear() { space.Clear(); set_index.clear(); group_index_tab.clear(); } }