Wittyshare  0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
WsMenu.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2006-Today Guy Deleeuw
3 *
4 * See the LICENSE file for terms of use.
5 */
6 
7 #include <dlfcn.h>
8 #include <stdio.h>
9 
10 #include <iostream>
11 
12 #include <boost/filesystem/operations.hpp>
13 
14 #include <Include/WsGlobalConfig.h>
15 
16 #include <Wt/WLogger>
17 #include <Wt/WTheme>
18 #include <Wt/WText>
19 #include <Wt/WLink>
20 #include <Wt/WResource>
21 
22 #include <Main/WsApplication.h>
23 
24 // TODO : pas top je sais
26 
27 #include "WsMenu.h"
28 
29 using namespace Wt;
30 
31 WsMenu::WsMenu(WContainerWidget* parent)
32  : WContainerWidget(parent), m_bDebug(false)
33 {
34  m_sCurPath = WsApp->internalPath();
35 }
36 
37 WsMenu::WsMenu(const std::string& path, WContainerWidget* parent)
38  : WContainerWidget(parent), m_bDebug(false), m_sCurPath(path)
39 {
40 }
41 
43 {
44 }
45 
47 {
48  WContainerWidget::load();
49  addStyleClass("WsMenu");
50  doLoadCurPath();
51  wApp->internalPathChanged().connect(SLOT(this, WsMenu::doPathChanged));
52 }
53 
55 {
56  std::string rootPath = asString(option("rootPath")).toUTF8();
57  boost::algorithm::replace_all(rootPath, "&amp;", "&");
58  // Si pas de root path on prend l'internal Path
59  if ( rootPath.size() < 1 )
60  m_sCurPath = WsApp->internalPath();
61  else
62  m_sCurPath = rootPath;
63  std::string sWithoutPrefix = WsApp->WsModules().pathWithoutPrefix(m_sCurPath);
64  WsUser* pUser = WsApp->wsUser();
65  NodePtr tmpNode = pUser->getAccessRoot().get()->eatPath(sWithoutPrefix);
66  if ( !tmpNode.get() ) {
67  wApp->log("notice") << "WsMenu::doLoadCurPath - eatPath return NULL ";
68  return;
69  }
70  if ( tmpNode.get()->isRegularFile() ) {
71  tmpNode = pUser->getAccessRoot().get()->eatPath(boost::filesystem::path(sWithoutPrefix).parent_path().string());
72  if ( !tmpNode.get() ) {
73  wApp->log("notice") << "WsMenu::doLoadCurPath - eatPath on parent return NULL ";
74  return;
75  }
76  }
77  NodePtr startNode = pUser->getAccessRoot();
78  if ( !startNode.get() ) {
79  wApp->log("notice") << "WsMenu::doLoadCurPath - startNode = " << startNode;
80  return;
81  }
82  NodePtr pNode = startNode.get()->eatPath(tmpNode.get()->getPath().string());
83  if ( !pNode.get() ) return;
84  if ( asString(option("useTitle")) == "true" ) {
85  std::string sTitle(pNode.get()->getDisplayName());
86  boost::algorithm::replace_all(sTitle, "&", "&amp;");
87  WText* title = new WText(sTitle);
88  title->addStyleClass("WsMenuTitle");
89  addWidget(title);
90  }
91  WMenu* menuParent = 0;
92  if ( asString(option("useButtons")) != "true" )
93  menuParent = new WMenu(this);
94  if ( asString(option("showRoot")) == "true" )
95  if ( pNode.get()->getPath() == "/" ) {
96  createMenu(pNode, menuParent);
97  }
98  loadMenu(pNode, menuParent);
99  if ( asString(option("useImages")) == "true" )
100  loadImage(pNode);
101 }
102 
103 void WsMenu::loadMenu(NodePtr pNodeParent, WMenu* menuParent)
104 {
105  std::vector<NodePtr> dirNode = pNodeParent.get()->getAll();
106  for (std::vector<NodePtr>::iterator it = dirNode.begin(); it != dirNode.end(); ++it) {
107  NodePtr curNode = *it;
108  if(curNode.get()->getDisplayInMenu())
109  createMenu(curNode, menuParent);
110  }
111 }
112 
113 void WsMenu::createMenu(NodePtr curNode, WMenu* menuParent)
114 {
115  std::string path2Icon;
116  WsUser* pUser = WsApp->wsUser();
117  std::string sIcon = curNode.get()->getProperties().get()->get("global", "icon", "");
118  if ( sIcon.size() > 1 ) {
119  NodePtr tmpNode = curNode;
120  if ( tmpNode.get()->isRegularFile() )
121  tmpNode = curNode.get()->getParent();
122  if ( tmpNode.get() ) {
123  path2Icon = tmpNode.get()->getFullPath().string() + "/ws.res/icones/" + sIcon;
124  if ( !boost::filesystem::exists(path2Icon) )
125  path2Icon.clear();
126  else {
127  boost::algorithm::replace_first(path2Icon, WsApp->docRoot(), "");
128  }
129  }
130  }
131  if ( asString(option("useButtons")) == "true" ) {
132  if ( curNode.get()->getPath().string() != "/" )
133  if ( asString(option("useSeparator")) == "true" ) {
134  WText* pText = new WText("|", this);
135  pText->addStyleClass("WsMenuSep");
136  }
137  WPushButton* button = new WPushButton(curNode.get()->getDisplayName(true), this);
138  m_vPushButton.push_back(button);
139  if ( path2Icon.size() > 1 ) {
140  button->setIcon(WLink(WLink::Url, path2Icon));
141  if ( curNode.get()->getProperties().get()->get("global", "button_text", "true") == "false" )
142  button->setText("");
143  }
144  // TODO : Ameliorer cette fonction
145  if ( (curNode.get()->isDirectory() && asString(option("directorySelectable")) == "true") ||
146  pUser->isAdministrator() || pUser->isEditor() ||
147  (asString(option("showRoot")) == "true" && curNode.get()->getPath() == "/")
148  ) {
149  button->setLink(WLink(WLink::InternalPath, curNode.get()->getPath().string()));
150  }
151  if ( curNode.get()->isRegularFile() ) {
152  button->setLink(makeLink(curNode.get()->getPath().string(), false));
153  if ( button->link().type() == WLink::Url )
154  button->setLinkTarget(TargetNewWindow);
155  }
156  bool popupAllowed = (curNode.get()->getProperties().get()->get("global", "allow_popup", "true") == "true" ? true : false);
157  if ( curNode.get()->isDirectory() && popupAllowed && asString(option("usePopupMenu")) == "true" ) {
158  if ( !(asString(option("noRootPopup")) == "true" && curNode.get()->getPath() == "/") ) {
159  WPopupMenu* pPopup = new WPopupMenu();
160  pPopup->addStyleClass("wt-no-reparent");
161  // pPopup->resize(200, 150);
162  // pPopup->resize(WLength::Auto, 150);
163  // pPopup->setMaximumSize(WLength::Auto, 150);
164  // pPopup->setMaximumSize(300, 150);
165  // pPopup->setHeight(150);
166  loadPopupMenu(curNode, pPopup);
167  button->setMenu(pPopup);
168  pPopup->setAutoHide(true);
169  button->mouseWentOver().connect(boost::bind(&WsMenu::onMouseWentOver, this, button));
170  button->setMouseOverDelay(50);
171  }
172  }
173  } else { // No buttons, standard menu
174  if ( curNode.get()->getPath().string() != "/" )
175  menuParent->addSeparator();
176  WMenuItem* pItem = menuParent->addItem(curNode.get()->getDisplayName(true));
177  pItem->setLink(WLink(WLink::InternalPath, curNode.get()->getPath().string()));
178  if ( path2Icon.size() > 1 )
179  pItem->setIcon(path2Icon);
180  if ( curNode.get()->isDirectory() && asString(option("usePopupMenu")) == "true" )
181  if ( curNode.get()->getDirectories().size() ) {
182  WPopupMenu* pPopup = new WPopupMenu();
183  pPopup->addStyleClass("wt-no-reparent");
184  loadPopupMenu(curNode, pPopup);
185  pItem->setMenu(pPopup);
186  }
187  }
188 }
189 
190 void WsMenu::onMouseWentOver(WPushButton* pButton)
191 {
192  if ( !pButton ) return;
193  if ( !pButton->menu() ) return;
194  WPopupMenu* pPopup = dynamic_cast<WPopupMenu*>(pButton->menu());
195  if ( asString(option("align")) == "right" )
196  pPopup->popup(pButton, Wt::Horizontal);
197  else
198  pPopup->popup(pButton, Wt::Vertical);
199 }
200 
201 void WsMenu::loadPopupMenu(NodePtr pNodeParent, Wt::WPopupMenu* menuParent)
202 {
203  std::vector<NodePtr> dirNode = pNodeParent->getAll();
204  for (std::vector<NodePtr>::iterator it = dirNode.begin(); it != dirNode.end(); ++it) {
205  NodePtr curNode = *it;
206  if(!curNode.get()->getDisplayInMenu())
207  continue;
208  bool popupAllowed = (curNode.get()->getProperties().get()->get("global", "allow_popup", "true") == "true" ? true : false);
209  if ( curNode.get()->isDirectory() && popupAllowed ) {
210  WPopupMenu* pSubPopupMenu = new WPopupMenu();
211  loadPopupMenu(curNode, pSubPopupMenu);
212  WMenuItem* pMenuItem = menuParent->addMenu(curNode.get()->getDisplayName(true), pSubPopupMenu);
213  if ( asString(option("directorySelectable")) == "true" )
214  pMenuItem->setLink(WLink(WLink::InternalPath, curNode.get()->getPath().string()));;
215  } else {
216  WPopupMenuItem* pPopupItem = menuParent->addItem(curNode.get()->getDisplayName(true));
217  pPopupItem->setLink(makeLink(curNode.get()->getPath().string(), true));
218  if ( pPopupItem->link().type() == WLink::Url )
219  pPopupItem->setLinkTarget(TargetNewWindow);
220  }
221  }
222 }
223 
224 WLink WsMenu::makeLink(const std::string& path, bool bUseIcon)
225 {
226  WsUser* pUser = WsApp->wsUser();
227  std::string m_sDocumentRoot = pUser->getRootPath(); // /var/www/demo_site
228  std::string m_httpDocumentRoot = gdWApp->getParameter("DOCUMENT_ROOT", "/var/www");
229  std::string m_sRelativeDocumentRoot = m_sDocumentRoot;
230  boost::algorithm::replace_first(m_sRelativeDocumentRoot, m_httpDocumentRoot, ""); // /demo_site
231  WLink lnk;
232  std::string strExt(boost::filesystem::extension(path));
233  if ( strExt == "" || strExt == ".fhtml" || strExt == ".rpg" || strExt == ".itpl" || strExt == ".form" || strExt == ".youtube" )
234  lnk.setInternalPath(path);
235  else {
236  if ( strExt == ".url" ) {
237  boost::filesystem::path urlFile(m_sDocumentRoot + path);
238  std::string sUrl;
239  std::ifstream f(urlFile.string().c_str());
240  std::getline(f, sUrl); // url without CR
241  boost::algorithm::replace_all(sUrl, "link=", "");
242  lnk.setUrl(sUrl);
243  } else
244  lnk.setUrl(m_sRelativeDocumentRoot + path);
245  }
246  return lnk;
247 }
248 
249 void WsMenu::loadImage(NodePtr pNodeParent)
250 {
251  std::string endPath(GlobalConfig::PathToImages);
252  std::string curDir = pNodeParent->getFullPath().string() + endPath;
253  if ( !boost::filesystem::exists(curDir) ) return;
254  WsImages2* pImg = new WsImages2(); //dynamic_cast<WsImages2*>(WsApp->WsModules().module("WsModImages2")->createContents());
255  pImg->setOptions(options());
256  long delay = asNumber(option("image_delay"));
257  if ( delay != -1 )
258  pImg->setOption("image_delay", delay);
259  pImg->setOption("imageInBackground", true);
260  pImg->setOption("reactWhenPathChange", false);
261  pImg->setOption("plusWidget", false);
262  pImg->setOption("textWidget", false);
263  std::string curPathUrl = curDir;
264  boost::algorithm::replace_first(curPathUrl, wApp->docRoot(), "");
265  pImg->setOption("imagesPath", std::string(curPathUrl));
266  pImg->build();
267  if ( !pImg->count() ) {
268  delete pImg;
269  WApplication::instance()->log("notice") << "WsMenu::load : has no images path = " << pNodeParent->getPath().string();
270  return;
271  }
272  addWidget(pImg);
273 }
274 
275 void WsMenu::doPathChanged(std::string newPath)
276 {
277  if ( asString(option("useInternalPath")) == "true" ) {
278  clear();
279  doLoadCurPath();
280  }
281  doSelectedMenu(newPath);
282 }
283 
284 void WsMenu::doSelectedMenu(std::string newPath)
285 {
286  return;
287  for (int iBut = 0; iBut < m_vPushButton.size(); ++iBut) {
288  m_vPushButton[iBut]->removeStyleClass("WsSelected");
289  const WLink& lnk = m_vPushButton[iBut]->link();
290  std::string curPath;
291  if ( lnk.type() == Wt::WLink::InternalPath ) curPath = lnk.internalPath().toUTF8();
292  // if ( lnk.type() == Wt::WLink::Url ) curPath = lnk.url();
293  // if ( lnk.type() == Wt::WLink::Resource ) curPath = lnk.resource()->internalPath(); // TODO : Wich # between internalPath & url ?
294  if ( curPath.compare(0, curPath.size(), newPath) != 0 ) continue;
295  m_vPushButton[iBut]->addStyleClass("WsSelected");
296  WPopupMenu* pPopup = m_vPushButton[iBut]->menu();
297  // if ( m_vPushButton[iBut]->
298  }
299 }
300 
const std::string PathToImages
boost::shared_ptr< WsAbstractNode > NodePtr
Wt::WLink makeLink(const std::string &path, bool bUseIcon=false)
Definition: WsMenu.cpp:224
std::string m_sCurPath
Definition: WsMenu.h:42
void build()
Build the vector.
Definition: WsImages2.cpp:96
void createMenu(NodePtr pNode, Wt::WMenu *menuParent)
Definition: WsMenu.cpp:113
const std::vector< WsOption > & options() const
Get all options.
Definition: WsOption.cpp:70
void loadImage(NodePtr pNodeParent)
Definition: WsMenu.cpp:249
Interface that provides differents methods for accessing the FsTree as well as other features...
Definition: WsUser.h:33
void loadPopupMenu(NodePtr pNodeParent, Wt::WPopupMenu *menuParent)
Definition: WsMenu.cpp:201
int count()
Return the number of images.
Definition: WsImages2.cpp:172
void doPathChanged(std::string newPath)
Definition: WsMenu.cpp:275
void doSelectedMenu(std::string newPath)
Definition: WsMenu.cpp:284
void setOption(const std::string &attribute, boost::any value)
Set an options if previously set, update the value.
Definition: WsOption.cpp:47
bool isEditor()
Definition: WsUser.cpp:179
const boost::any & option(const std::string &attribute) const
Get an options value.
Definition: WsOption.cpp:62
const std::string getRootPath()
return the root path of the filesystem tree, example : /var/www/demo_site
Definition: WsUser.cpp:55
#define WsApp
Define a shortcut to the application instance.
Definition: WsApplication.h:62
void setOptions(const std::vector< WsOption > &vOptions)
Set all options.
Definition: WsOption.cpp:57
bool isAdministrator()
Definition: WsUser.cpp:184
NodePtr getAccessRoot()
return the root node of the access tree starting from the root
Definition: WsUser.cpp:50
void onMouseWentOver(Wt::WPushButton *pButton)
Definition: WsMenu.cpp:190
void doLoadCurPath()
Definition: WsMenu.cpp:54
std::vector< Wt::WPushButton * > m_vPushButton
Definition: WsMenu.h:44
void loadMenu(NodePtr pNodeParent, Wt::WMenu *menuParent)
Definition: WsMenu.cpp:103
void load()
Definition: WsMenu.cpp:46
WsMenu(Wt::WContainerWidget *parent=0)
Definition: WsMenu.cpp:31
a wittyShare class that render images randomly
A class that render a menu.
~WsMenu()
Definition: WsMenu.cpp:42