319 lines
5.6 KiB
C++
Executable File
319 lines
5.6 KiB
C++
Executable File
/*
|
|
* 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 Key, class Value>
|
|
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.size() ; ++i)
|
|
{
|
|
if( tab[i].key == key )
|
|
{
|
|
added_new = false;
|
|
return &tab[i].value;
|
|
}
|
|
}
|
|
|
|
// there is no such an element in our table
|
|
// so we add a new item
|
|
tab.push_back(Item());
|
|
|
|
tab.back().key = key;
|
|
added_new = true;
|
|
|
|
return &tab.back().value;
|
|
}
|
|
|
|
/*
|
|
returning true if Get() method has inserted a new Item
|
|
*/
|
|
bool AddedNew()
|
|
{
|
|
return added_new;
|
|
}
|
|
|
|
|
|
void Clear()
|
|
{
|
|
tab.clear();
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
std::vector<Item> tab;
|
|
bool added_new;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
namespace Menu
|
|
{
|
|
using namespace TemplatesFunctions;
|
|
using TemplatesFunctions::system;
|
|
|
|
extern int mount_par_menu_skip;
|
|
|
|
|
|
|
|
struct MenuDir
|
|
{
|
|
std::vector<Item> items;
|
|
size_t index;
|
|
std::wstring dir;
|
|
|
|
MenuDir()
|
|
{
|
|
index = 0;
|
|
}
|
|
};
|
|
|
|
|
|
static MenuDir * menu_dir = 0;
|
|
static DbItemQuery iq;
|
|
static Stack<std::wstring, MenuDir> 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 ; i<arg.size() ; ++i)
|
|
{
|
|
for(size_t x=0 ; x<menu_dir->items.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 ; x<menu_dir->items.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 ; a<len ; ++a)
|
|
{
|
|
if( menu_dir->items[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<EzcFun*>(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
|
|
|
|
|
|
|
|
|