/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2011, Tomasz Sowa * All rights reserved. * */ #include "templates/templates.h" #include "core/plugin.h" #include "core/item.h" #include "core/log.h" #include "core/misc.h" // !! temporarily template class Stack { public: typedef Key StackKey; typedef Value StackValue; struct Item { StackKey key; StackValue value; }; Stack() { added_new = false; } StackValue * Get(const StackKey & key) { for(size_t i=0 ; i tab; bool added_new; }; namespace Menu { using namespace TemplatesFunctions; using TemplatesFunctions::system; extern int mount_par_menu_skip; struct MenuDir { std::vector items; size_t index; std::wstring dir; MenuDir() { index = 0; } }; static MenuDir * menu_dir = 0; static DbItemQuery iq; static Stack menu_dir_stack; static size_t req_id = 0; // O(n^2) complexity void menu_dir_skip_items(long parent_id) { Mount * m = system->mounts.CalcMount(parent_id); if( !m || mount_par_menu_skip==-1 || !m->param[mount_par_menu_skip].defined ) return; const Mount::ParamRow::ParamArg & arg = m->param[mount_par_menu_skip].arg; for(size_t i=0 ; iitems.size() ; ) { if( menu_dir->items[x].url == arg[i] ) menu_dir->items.erase(menu_dir->items.begin() + x); else x += 1; } } } void menu_dir_skip_static_files() { for(size_t x=0 ; xitems.size() ; ) { if( menu_dir->items[x].type == Item::file && menu_dir->items[x].file_type != WINIX_ITEM_FILETYPE_NONE ) menu_dir->items.erase(menu_dir->items.begin() + x); else x += 1; } } void menu_dir_load_menu(long parent_id) { iq.SetAll(false, false); iq.sel_subject = true; iq.sel_url = true; iq.sel_sort_index = true; iq.sel_type = true; iq.sel_file = true; iq.WhereParentId(parent_id); db->GetItems(menu_dir->items, iq); menu_dir_skip_items(parent_id); menu_dir_skip_static_files(); // !! temporarily for debug purposes log << log1 << "Menu: db used" << logend; } void menu_dir_init(const std::wstring & path) { if( cur->request->id != req_id ) { menu_dir_stack.Clear(); req_id = cur->request->id; } menu_dir = menu_dir_stack.Get(path); if( !path.empty() && path[0] != '/' ) { log << log1 << "Menu: path for menu should not be relative" << logend; return; } if( menu_dir_stack.AddedNew() ) { if( path.empty() ) { // current directory menu_dir_load_menu(cur->request->dir_tab.back()->id); system->dirs.MakePath(cur->request->dir_tab, menu_dir->dir); } else { menu_dir->dir = path; Item * pdir = system->dirs.GetDir(path); if( pdir ) menu_dir_load_menu(pdir->id); else log << log1 << "Menu: I cannot find a directory: " << path << logend; } } } void menu_dir_tab(Info & i) { menu_dir_init(i.par); menu_dir->index = i.iter; i.res = menu_dir->index < menu_dir->items.size(); } void menu_dir_tab_subject(Info & i) { if( menu_dir->index < menu_dir->items.size() ) i.out << menu_dir->items[menu_dir->index].subject; } void menu_dir_tab_url(Info & i) { if( menu_dir->index < menu_dir->items.size() ) i.out << menu_dir->items[menu_dir->index].url; } void menu_dir_tab_link(Info & i) { if( menu_dir->index < menu_dir->items.size() ) { i.out << menu_dir->dir; if( !IsLastSlash(menu_dir->dir) ) i.out << '/'; i.out << menu_dir->items[menu_dir->index].url; } } void menu_dir_tab_is_current(Info & i) { if( menu_dir->index < menu_dir->items.size() ) { i.res = (menu_dir->items[menu_dir->index].id == cur->request->last_item->id); } } // returning true if the dir tab element is a first parent for current item void menu_dir_tab_is_first_parent_for_current_item(Info & i) { if( menu_dir->index < menu_dir->items.size() ) i.res = (menu_dir->items[menu_dir->index].id == cur->request->last_item->parent_id); } // returning true if the dir tab element is a parent for current item // (it don't have to be the first parent - it can be a descendant) void menu_dir_tab_is_parent_for_current_item(Info & i) { if( menu_dir->index < menu_dir->items.size() ) { size_t len = cur->request->dir_tab.size(); // at least one if( !cur->request->is_item ) { // the last item is a directory so we don't get it into account len -= 1; } for(size_t a=0 ; aitems[menu_dir->index].id == cur->request->dir_tab[a]->id ) { i.res = true; break; } } } } void AddEzcFunctions(PluginInfo & info) { using TemplatesFunctions::EzcFun; EzcFun * fun = reinterpret_cast(info.p1); fun->Insert("menu_dir_tab", menu_dir_tab); fun->Insert("menu_dir_tab_subject", menu_dir_tab_subject); fun->Insert("menu_dir_tab_url", menu_dir_tab_url); fun->Insert("menu_dir_tab_link", menu_dir_tab_link); fun->Insert("menu_dir_tab_is_current", menu_dir_tab_is_current); fun->Insert("menu_dir_tab_is_first_parent_for_current_item", menu_dir_tab_is_first_parent_for_current_item); fun->Insert("menu_dir_tab_is_parent_for_current_item", menu_dir_tab_is_parent_for_current_item); } } // namespace