/* * 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 Key1 StackKey1; typedef Key2 StackKey2; typedef Value StackValue; struct Item { StackKey1 key1; StackKey2 key2; StackValue value; }; Stack() { added_new = false; } StackValue * Get(const StackKey1 & key1, const StackKey2 & key2) { 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; static std::wstring strempty; // warning: 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, const std::wstring & arg) { 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); if( arg == L"images" ) { iq.WhereType(Item::file); iq.WhereFileType(WINIX_ITEM_FILETYPE_IMAGE); } else if( arg == L"dirs" ) { iq.WhereType(Item::dir); } else if( arg == L"files" ) { iq.WhereType(Item::file); } else if( arg == L"" ) { } else { log << log1 << "Menu: unknown parameter: " << arg << logend; } db->GetItems(menu_dir->items, iq); menu_dir_skip_items(parent_id); // !! FIXME: in the future is better to have DbItemQuery with a special option // that skips static files if( arg == L"" ) menu_dir_skip_static_files(); // !! temporarily for debug purposes log << log1 << "Menu: db used" << logend; } void menu_dir_init(const std::wstring & path, const std::wstring & arg) { menu_dir = menu_dir_stack.Get(path, arg); if( menu_dir_stack.AddedNew() ) { if( path.empty() ) { // current directory menu_dir_load_menu(cur->request->dir_tab.back()->id, arg); 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, arg); else log << log1 << "Menu: I cannot find a directory: " << path << logend; } } } void menu_dir_init(const std::vector & params) { if( cur->request->id != req_id ) { menu_dir_stack.Clear(); menu_dir = 0; req_id = cur->request->id; } if( !params.empty() && !params[0].empty() && params[0][0] != '/' ) { log << log1 << "Menu: path for a menu should not be relative" << logend; return; } strempty.clear(); // for safety if( params.empty() ) menu_dir_init(strempty, strempty); else if( params.size() == 1 ) menu_dir_init(params[0], strempty); else menu_dir_init(params[0], params[1]); } void menu_dir_tab(Info & i) { menu_dir_init(i.params); menu_dir->index = i.iter; i.res = menu_dir->index < menu_dir->items.size(); } void menu_dir_tab_subject(Info & i) { if( menu_dir && 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 && 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 && 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 && 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 && 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 && 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