Wittyshare  0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
WsSiteMapView.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-Today G. Deleeuw
3  *
4  * See the LICENSE file for terms of use.
5  */
6 
7 // TODO :
8 // - toolbar button UP
9 // - ajouter root au tree left
10 // - quand tree left width change : resize column0 du treeview
11 // - si pas de container pas de Hscrollbar quand resize du panel
12 // - quand Vscrollbar plus de button sort
13 
14 #include <stdio.h>
15 
16 #include <boost/algorithm/string/replace.hpp>
17 #include <boost/lexical_cast.hpp>
18 
19 #include <iostream>
20 #include <time.h>
21 
22 #include <Wt/WHBoxLayout>
23 #include <Wt/WVBoxLayout>
24 #include <Wt/WStandardItem>
25 #include <Wt/WText>
26 #include <Wt/WStackedWidget>
27 #include <Wt/WItemDelegate>
28 #include <Wt/WTheme>
29 
30 #include <gdcore/gdCore.h>
31 
32 #include "WsSiteMapView.h"
33 #include "WsApplication.h"
34 #include "WsErrorPage.h"
35 
36 using namespace Wt;
37 
38 WsSiteMapItem::WsSiteMapItem() : WStandardItem()
39 { }
40 
41 WsSiteMapItem::WsSiteMapItem(const WString& text) : WStandardItem(text)
42 { }
43 
45 {
46  m_node = pNode;
47 }
48 
50 {
51  return m_node;
52 }
53 
54 
55 
56 
57 
58 WsSiteMapView::WsSiteMapView(gdwtcore::viewType nViewType, gdWFileView::tbFlags flags, WContainerWidget* parent)
59  : WContainerWidget(parent), m_viewType(nViewType), m_tbFlags(flags), m_pModelTree(0), m_pModelView(0), m_pTVTree(0), m_pTVView(0),
60  m_pTb(0), m_bOnDataChanged(false), m_pMenu(0), m_bOnRename(false), m_bLogSiteMap(false), m_pMb(0)
61 
62 {
63  if ( WString::tr("byObjectStyleSheet").narrow() == "true" )
64  wApp->useStyleSheet(wApp->theme()->resourcesUrl() + "wittyshare/Css/WsSiteMapView.css");
65  addStyleClass("WsSiteMapView");
66  if (WsLayoutProperties::instance()->get("sitemap", "log", "false") == "true")
67  m_bLogSiteMap = true;
68  wApp->messageResourceBundle().use(wApp->docRoot() + wApp->resourcesUrl() + "wittyshare/Transl/WsSiteMapView");
69  if ( m_tbFlags == gdWFileView::tbDefault ) {
70  int nTmp = gdWFileView::tbDefault | gdWFileView::tbUseDummy;
71  m_tbFlags = (gdWFileView::tbFlags) nTmp;
72  }
73  setOverflow(WContainerWidget::OverflowHidden);
74  WsUser* pUser = WsApp->wsUser();
75  m_sRootPath = pUser->getRootPath(); // /var/www/demo_site
76  m_sSiteMap = WsLayoutProperties::instance()->get("sitemap", "root", "/SiteMap"); // /SiteMap
77  m_sRootSiteMap = m_sRootPath + m_sSiteMap; // /var/www/demo_site/SiteMap
78  m_pTreecurNode = pUser->getAccessRoot();
79  load();
80 }
81 
83 {
84  if ( m_bLogSiteMap )
85  wApp->log("notice") << "WsSiteMapView::~WsSiteMapView()";
86 }
87 
89 {
90  WContainerWidget::load();
91  m_pModelTree = new WStandardItemModel(0, 1, this);
92  m_pModelTree->setHeaderData(0, WString::tr("WsSiteMapView-Name"));
93  m_pModelTree->setSortRole(UserRole);
94  std::vector<WStandardItem*> pRow;
95  WsSiteMapItem* newItem = new WsSiteMapItem(m_sSiteMap);
96  newItem->setData("1" + m_sRootSiteMap, UserRole); // le path complet
97  newItem->setIcon(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/folder.png");
98  pRow.push_back(newItem);
99  // TODO : creer une node et call setNode
100  //m_pModelTree->invisibleRootItem()->appendRow(pRow);
101  m_pTVTree = new WTreeView();
102  // m_pTVTree->setLayoutSizeAware(true);
103  m_pTVTree->setModel(m_pModelTree);
104  m_pTVTree->setColumnResizeEnabled(true);
105  m_pTVTree->setSortingEnabled(true);
106  m_pTVTree->setSelectionMode(SingleSelection);
107  m_pTVTree->selectionChanged().connect(SLOT(this, WsSiteMapView::onTreeSelectionChanged));
108  // m_pTVTree->setDropsEnabled(true);
109  // avec Node m_pTVTree->expand(newItem->index());
110  m_pTVTree->expanded().connect(SLOT(this, WsSiteMapView::onTreeExpanded));
111  // double dblWidth = (parent->width().value() * 30) / 100;
112  // m_pTVTree->resize(WLength(dblWidth, parent->width().unit()), WLength::Auto);
113  // m_pTVTree->resize(WLength::Auto, 550);
114  // m_pTVTree->resize(WLength::Auto, WLength::Auto);
115  // m_pTVTree->resize(WLength(30, WLength::Percentage), WLength(100, WLength::Percentage));
116  m_pModelView = new WStandardItemModel(0, 3);
117  m_pModelView->setHeaderData(0, WString::tr("WsSiteMapView-Name"));
118  m_pModelView->setHeaderData(1, WString::tr("WsSiteMapView-Size"));
119  m_pModelView->setHeaderData(2, WString::tr("WsSiteMapView-Date"));
120  m_pModelView->setSortRole(UserRole);
121  m_pModelView->itemChanged().connect(SLOT(this, WsSiteMapView::onDirectoryNameChanged));
122  //TODO : implement the load method for the treeView and treeTree
123  if ( m_tbFlags & gdWFileView::tbUseLeftTree )
124  loadTree(m_pModelTree->invisibleRootItem(), m_pTreecurNode, gdWFileView::noSkipParent);
125  m_pTVView = new WTreeView();
126  m_pTVView->setModel(m_pModelView);
127  m_pTVView->setColumnResizeEnabled(true);
128  m_pTVView->setSortingEnabled(true);
129  m_pTVView->setAlternatingRowColors(true);
130  // m_pTVView->setColumnWidth(0, 200);
131  m_pTVView->setColumnWidth(1, 80);
132  m_pTVView->setColumnWidth(2, 80);
133  // m_pTVView->setRowHeight(14);
134  m_pTVView->setSelectionMode(ExtendedSelection);
135  m_pTVView->setColumnAlignment(1, AlignRight);
136  m_pTVView->doubleClicked().connect(SLOT(this, WsSiteMapView::onViewDblClick));
137  m_pTVView->selectionChanged().connect(SLOT(this, WsSiteMapView::onViewSelectionChanged));
138  m_pTVView->expanded().connect(SLOT(this, WsSiteMapView::onViewExpanded));
139  // m_pTVView->setDragEnabled(true);
140  m_pTVView->setEditTriggers(WAbstractItemView::SingleClicked);
141  WItemDelegate* delegate = new WItemDelegate(this);
142  delegate->setTextFormat("%s");
143  m_pTVView->setItemDelegate(delegate);
144  // Pas necessaire, sera declenche par setRelativePath ?
145  // init(m_pTreecurNode);
146  WText* pTitle = new WText("Site Map");
147  pTitle->addStyleClass("WsTitle");
148  WHBoxLayout* hbox = new WHBoxLayout();
149  if ( m_tbFlags & gdWFileView::tbUseLeftTree )
150  hbox->addWidget(m_pTVTree, 1);
151  hbox->addWidget(m_pTVView, 2);
152  if ( m_tbFlags & gdWFileView::tbUseLeftTree )
153  hbox->setResizable(0, true, WLength(33, WLength::Percentage));
154  WVBoxLayout* vbox = new WVBoxLayout();
155  vbox->addWidget(pTitle, 0);
156  if ( m_tbFlags & gdWFileView::tbUseToolbar ) {
157  makeToolbar();
158  vbox->addWidget(m_pTb, 0);
159  }
160  vbox->addLayout(hbox, 1);
161  setLayout(vbox);
162 }
163 
164 std::string WsSiteMapView::path2SiteMapPath(const std::string& path)
165 {
166  std::string str(path);
167  boost::algorithm::replace_first(str, m_sRootSiteMap, m_sRootPath);
168  return str;
169 }
170 
171 std::string WsSiteMapView::SiteMapPath2path(const std::string& siteMapPath)
172 {
173  std::string str(siteMapPath);
174  boost::algorithm::replace_first(str, m_sRootPath, m_sRootSiteMap);
175  return str;
176 }
177 
178 void WsSiteMapView::setRelativePath(const std::string& relativePath)
179 {
180  if ( !loaded() ) load();
181  std::string str(relativePath);
182  boost::algorithm::replace_first(str, m_sSiteMap, "");
183  if ( str.size() < 1 )
184  str = "/";
185  WsUser* pUser = WsApp->wsUser();
186  NodePtr node = m_pTreecurNode.get()->eatPath(str);
187  if (!node.get()){
188  wApp->root()->clear();
189  wApp->root()->addWidget(new WsErrorPage(WsErrorPage::NotFound, str,pUser, ""));
190  return;
191  }
192  init(node);
193 }
194 
196 {
197  if (!pNode.get())
198  return;
199  if ( m_pModelView->rowCount() )
200  m_pModelView->removeRows(0, m_pModelView->rowCount());
201  if ( m_tbFlags & gdWFileView::tbUseLeftTree )
202  treeMatchPath(pNode);
203  else if ( !loadTree(m_pModelView->invisibleRootItem(), pNode, gdWFileView::noSkipParent) ) {
204  wApp->log("error") << "WsSiteMapView::init() return with bad loadTree !!! ";
205  return;
206  }
207  m_selectedDirectory = m_sRootSiteMap + pNode.get()->getPath().string();
208 }
209 
210 bool WsSiteMapView::treeTraverse(WStandardItem* rootItem, const std::vector<std::string>& vPath, int nLevel)
211 {
212  if ( nLevel >= vPath.size() ) return false;
213  for (int nItem = 0; nItem < rootItem->rowCount(); ++nItem) {
214  WsSiteMapItem* tmpItem = dynamic_cast<WsSiteMapItem*>(rootItem->child(nItem, 0));
215  std::string str = tmpItem->text().toUTF8();
216  if ( (vPath[nLevel]) == str )
217  if ( nLevel == vPath.size() - 1 ) {
218  m_pTVTree->select(tmpItem->index());
219  m_pTVTree->scrollTo(tmpItem->index());
220  return true;
221  } else {
222  m_pTVTree->expand(tmpItem->index());
223  onTreeExpanded(tmpItem->index());
224  return treeTraverse(tmpItem, vPath, ++nLevel);
225  }
226  }
227  return false;
228 }
229 
231 {
232  if (pNode.get() == 0)
233  return;
234  WsUser* pUser = WsApp->wsUser();
235  std::string myPath(pNode.get()->getPath().string());
236  std::string rootPath = m_pTreecurNode.get()->getPath().string();
237  std::vector<std::string> vPath;
238  NodePtr curNode = pNode;
239  // Bug dans getAccessRoot ?
240  if ( rootPath.size() < 1 )
241  rootPath = "/";
242  vPath.push_back(rootPath);
243  if ( pNode != m_pTreecurNode )
244  while (curNode.get() != 0 && curNode.get()->getParent() ) {
245  curNode = curNode.get()->getParent();
246  vPath.insert(vPath.begin() + 0, myPath);
247  myPath = curNode.get()->getPath().string();
248  if ( curNode != m_pTreecurNode ) break;
249  }
250  if ( !treeTraverse(m_pModelTree->invisibleRootItem(), vPath, 0) ) {
251  if ( m_bLogSiteMap )
252  wApp->log("notice") << "WsSiteMapView::treeMatchPath() treetraverse ";
253  }
254  loadTree(m_pModelView->invisibleRootItem(), pNode, gdWFileView::noSkipParent);
255  WModelIndexSet pSet = m_pTVTree->selectedIndexes();
256  if ( pSet.size() )
257  m_pTVTree->scrollTo(*pSet.begin());
258 }
259 
260 /* loadTree et loadFile utilise le path complet dans data UserRole, prefixe 1 = directory, 2 = file
261  ceci afin de conserver les repertoires groupes lors d'un tri colonne.
262 */
263 bool WsSiteMapView::loadTree(WStandardItem* currentItem, NodePtr pNode, gdWFileView::skipMode skipParentDir)
264 {
265  WsUser* pUser = WsApp->wsUser();
266  if (!pNode.get())
267  return false;
268  if ( m_bLogSiteMap )
269  if ( currentItem->model() == m_pModelTree )
270  if ( m_bLogSiteMap )
271  wApp->log("notice") << "WsSiteMapView::loadTree() m_pModelTree pNode full path = " << pNode.get()->getPath().string();
272  if ( pNode.get()->isDirectory() ) {
273  if ( !skipParentDir && (pNode != m_pTreecurNode) && !(m_tbFlags & gdWFileView::tbUseLeftTree) ) {
274  std::vector<WStandardItem*> pRow;
275  std::string newPath = pNode.get()->getPath().string();
276  WsSiteMapItem* newItem = new WsSiteMapItem("..");
277  newItem->setData("1" + path2SiteMapPath(newPath), UserRole);
278  newItem->setIcon(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/folder.png");
279  pRow.push_back(newItem);
280  pRow.push_back(new WsSiteMapItem());
281  pRow.push_back(new WsSiteMapItem());
282  currentItem->appendRow(pRow);
283  }
284  std::vector<NodePtr> tmpNode;
285  std::vector<NodePtr>& dirNode = tmpNode;
286  if ( currentItem->model() == m_pModelTree ) dirNode = pNode.get()->getDirectories();
287  else dirNode = pNode.get()->getAll();
288  for (std::vector<NodePtr>::iterator it = dirNode.begin(); it != dirNode.end(); ++it) {
289  NodePtr curNode = *it;
290  // Items not displayed in view are still visible in the sitemap to the administrator
291  if ( !(pUser->isAdministrator() || pUser->isEditor()) )
292  if ( curNode.get()->getProperties().get()->get("global", "in_view", "true") != "true" ) continue;
293  // Do not display ws.res directories in the sitemap
294  if (curNode.get()->getName() == "ws.res") continue;
295  std::string curPath = m_sRootPath + curNode.get()->getPath().string();
296  if ( curNode.get()->isDirectory() ) {
297  if ( !loadFolder(currentItem, curPath, curNode) ) return false;
298  } else {
299  if ( currentItem->model() == m_pModelTree ) continue;
300  if ( !loadFile(currentItem, curPath, curNode) ) return false;
301  }
302  }
303  if ( currentItem->model() == m_pModelView )
304  m_pModelView->sort(0);
305  }
306  return true;
307 }
308 
309 bool WsSiteMapView::loadFolder(WStandardItem* currentItem, const std::string& newPath, NodePtr curNode, bool bEdit)
310 {
311  WsSiteMapItem* newItem = new WsSiteMapItem(WString::fromUTF8(curNode.get()->getName())); // le nom.extension du fichier
312  newItem->setNode(curNode);
313  newItem->setData("1" + newPath, UserRole); // le path complet
314  newItem->setIcon(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/folder.png");
315  if ( currentItem->model() == m_pModelTree ) {
316  currentItem->appendRow(newItem);
317  } else {
318  std::vector<WStandardItem*> pRow;
319  pRow.push_back(newItem);
320  pRow.push_back(new WsSiteMapItem());
321  pRow.push_back(new WsSiteMapItem());
322  currentItem->appendRow(pRow);
323  if ( bEdit ) {
324  // m_pModelView->sort(0);
325  newItem->setFlags(ItemIsSelectable | ItemIsEditable);
326  WModelIndexSet pSet;
327  m_pTVView->setSelectedIndexes(pSet);
328  m_pTVView->edit(newItem->index());
329  }
330  }
331  if ( curNode.get()->getDirectories().size() == 0 ) return true;
332  if ( currentItem->model() == m_pModelTree )
333  if ( m_tbFlags & gdWFileView::tbUseDummy )
334  newItem->appendRow(new WsSiteMapItem());
335  else
336  return loadTree(newItem, newItem->node(), gdWFileView::noSkipParent);
337  else {
338  if ( m_tbFlags & gdWFileView::tbUseLeftTree ) return true;
339  std::vector<WStandardItem*> pRowChild;
340  pRowChild.push_back(new WsSiteMapItem());
341  pRowChild.push_back(new WsSiteMapItem());
342  pRowChild.push_back(new WsSiteMapItem());
343  newItem->appendRow(pRowChild);
344  }
345  return true;
346 }
347 
348 bool WsSiteMapView::loadFile(WStandardItem* currentItem, const std::string& currentPath, NodePtr curNode)
349 {
350  long fsize = curNode.get()->getSize();
351  std::string strSize = boost::lexical_cast<std::string>(fsize);
352  std::string strDate;
353  std::time_t t = curNode.get()->getModifyDate();
354  struct tm ttm;
355  char c[100];
356  localtime_r(&t, &ttm);
357  strftime(c, 100, "%Y-%m-%d", &ttm);
358  strDate = c;
359  std::vector<WStandardItem*> pRow;
360  WsSiteMapItem* newItem = new WsSiteMapItem(WString::fromUTF8(curNode.get()->getName())); // le nom.extension du fichier
361  newItem->setNode(curNode);
362  newItem->setData("2" + currentPath, UserRole); // le path complet du parent
363  // newItem->setFlags(newItem->flags() | ItemIsDragEnabled);
364  newItem->setIcon(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/file.png");
365  pRow.push_back(newItem);
366  WsSiteMapItem* colSize = new WsSiteMapItem(strSize);
367  colSize->setData(fsize, UserRole);
368  pRow.push_back(colSize);
369  WsSiteMapItem* colDate = new WsSiteMapItem(strDate);
370  colDate->setData(strDate, UserRole);
371  pRow.push_back(colDate);
372  currentItem->appendRow(pRow);
373  return true;
374 }
375 
377 {
378  WModelIndexSet pSet = m_pTVTree->selectedIndexes();
379  WModelIndexSet::iterator it = pSet.begin();
380  if ( pSet.empty() ) return;
381  WModelIndex idx = *it;
382  std::string str = asString(idx.data(UserRole)).toUTF8();
383  char type = str[0];
384  str.erase(0, 1);
385  boost::algorithm::replace_all(str, m_sRootPath, m_sSiteMap);
386  m_selectedDirectory = str;
387  m_selectedFile.clear();
388  WsSiteMapItem* pItem = dynamic_cast<WsSiteMapItem*>(m_pModelTree->itemFromIndex(idx));
389  if ( m_tbFlags & gdWFileView::tbUseDummy )
390  if ( !loadTree(pItem, pItem->node(), gdWFileView::skipParent) ) return;
391  m_pModelView->invisibleRootItem()->removeRows(0, m_pModelView->invisibleRootItem()->rowCount());
392  if ( !loadTree(m_pModelView->invisibleRootItem(), pItem->node(), gdWFileView::skipParent) ) return;
393  wApp->setInternalPath(str, true);
394  // fileSelected().emit(gdWFileView::none, str);
395 }
396 
397 void WsSiteMapView::onTreeExpanded(WModelIndex idx)
398 {
399  if ( idx.column() != 0 ) return;
400  std::string str = asString(idx.data(UserRole)).toUTF8();
401  char type = str[0];
402  str.erase(0, 1);
403  WsSiteMapItem* pItem = dynamic_cast<WsSiteMapItem*>(m_pModelTree->itemFromIndex(idx));
404  if ( m_tbFlags & gdWFileView::tbUseDummy ) {
405  pItem->removeRows(0, pItem->rowCount());
406  if ( !loadTree(pItem, pItem->node(), gdWFileView::skipParent) ) return;
407  pItem->sortChildren(0, Wt::AscendingOrder);
408  }
409 }
410 
411 
413 {
414  WModelIndexSet pSet = m_pTVView->selectedIndexes();
415  WModelIndexSet::iterator it = pSet.begin();
416  if ( pSet.empty() ) return;
417  WModelIndex idx = *it;
418  std::string str = asString(idx.data(UserRole)).toUTF8();
419  char type = str[0];
420  str.erase(0, 1);
421  // if ( m_bLogSiteMap )
422  boost::algorithm::replace_first(str, m_sRootPath, m_sSiteMap);
423  if ( type == '2' ) {
424  m_selectedDirectory.clear();
425  m_selectedFile = str;
426  fileSelected().emit(gdWFileView::selected, m_selectedFile);
427  // boost::algorithm::replace_first(str, "/SiteMap", "");
428  // wApp->setInternalPath(str, true);
429  } else {
430  // WsSiteMapItem* pItem = dynamic_cast<WsSiteMapItem*>(m_pModelView->itemFromIndex(idx));
431  m_selectedFile.clear();
432  m_selectedDirectory = str;
433  fileSelected().emit(gdWFileView::none, str);
434  }
435 }
436 
437 void WsSiteMapView::onViewDblClick(WModelIndex idx, WMouseEvent mouseEvent)
438 {
439  WModelIndex idxcol0;
440  if ( idx.column() != 0 ) {
441  if ( idx.parent().isValid() )
442  idxcol0 = idx.parent().child(idx.row(), 0);
443  else
444  idxcol0 = idx.child(idx.row(), 0);
445  } else
446  idxcol0 = idx;
447  if ( !idxcol0.isValid() ) return;
448  std::string str = asString(idxcol0.data(UserRole)).toUTF8();
449  char type = str[0];
450  str.erase(0, 1);
451  // if ( m_bLogSiteMap )
452  boost::algorithm::replace_first(str, m_sRootPath, m_sSiteMap);
453  //fprintf(stderr, "onDblclick - Type = %c, Selected path = %s\n", type, str.c_str());
454  if ( type == '1' ) {
455  //init(str);
456  } else {
457  m_selectedFile = str;
458  // if ( m_bLogSiteMap )
459  fileSelected().emit(gdWFileView::doubleClick, m_selectedFile);
460  }
461 }
462 
463 void WsSiteMapView::onViewExpanded(WModelIndex idx)
464 {
465  if ( idx.column() != 0 ) return;
466  std::string str = asString(idx.data(UserRole)).toUTF8();
467  char type = str[0];
468  str.erase(0, 1);
469  //fprintf(stderr, "onViewExpanded - Type = %c, Selected path = %s\n", type, str.c_str());
470  WsSiteMapItem* pItem = dynamic_cast<WsSiteMapItem*>(m_pModelView->itemFromIndex(idx));
471  if ( type == '1' ) {
472  pItem->removeRows(0, pItem->rowCount());
473  //if ( !loadTree(pItem, str, gdWFileView::skipParent) ) return;
474  // m_pModelView->sort(0);
475  }
476 }
477 
478 void WsSiteMapView::setCurrentPath(const std::string& currentPath)
479 {
480  //init(currentPath);
481 }
482 
484 {
485  return m_selectedDirectory;
486 }
487 
489 {
490  return m_selectedFile;
491 }
492 
494 {
495  if ( gdcore_isPathFile(m_selectedFile) ) return m_selectedFile;
496  else return m_selectedDirectory;
497 }
498 
500 {
501  //return m_fsRootPath.string();
502 }
503 
505 {
506  m_pTb = new gdToolbar();
507  m_tbiNewFolder = m_pTb->addToolbarItem(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/folder_new.png", WString::tr("WsSiteMapView-newfolder").toUTF8(), WString::tr("WsSiteMapView-newfolder-tooltips").toUTF8());
508  m_tbiNewFolder->clicked().connect(SLOT(this, WsSiteMapView::doNewFolder));
509  m_tbiDelete = m_pTb->addToolbarItem(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/Delete.png", WString::tr("WsSiteMapView-delete").toUTF8(), WString::tr("WsSiteMapView-delete-tooltips").toUTF8());
510  m_tbiDelete->clicked().connect(SLOT(this, WsSiteMapView::doConfirmDelete));
511  m_tbiRename = m_pTb->addToolbarItem(wApp->theme()->resourcesUrl() + "gdwtcore/Icons/rename.png", WString::tr("WsSiteMapView-rename").toUTF8(), WString::tr("WsSiteMapView-rename-tooltips").toUTF8());
512  m_tbiRename->clicked().connect(SLOT(this, WsSiteMapView::doRename));
513 }
514 
516 {
517  WModelIndexSet pSet = m_pTVView->selectedIndexes();
518  WModelIndexSet::iterator it = pSet.begin();
519  if ( pSet.empty() ) return;
520  WModelIndex idx = *it;
521  WsSiteMapItem* pItem = dynamic_cast<WsSiteMapItem*>( m_pModelView->itemFromIndex(m_pModelView->index(idx.row(), 0, m_pModelView->parent(idx))) );
522  pItem->setFlags(ItemIsSelectable | ItemIsEditable);
523  WModelIndexSet pSet2;
524  m_bOnRename = true;
525  m_pTVView->setSelectedIndexes(pSet2);
526  m_pTVView->edit(pItem->index());
527 }
528 
530 {
531  WModelIndexSet pSet = m_pTVView->selectedIndexes();
532  WModelIndexSet::iterator it = pSet.begin();
533  if ( pSet.empty() ) return;
534  WModelIndex idx = *it;
535  std::string str = asString(idx.data(UserRole)).toUTF8();
536  str.erase(0, 1);
537  //boost::algorithm::replace_all(str, m_fsRootPath.string(), "");
538  m_pMb = new WMessageBox("Confirm", "Remove " + str + " ?", Wt::Question, Wt::Ok | Wt::Cancel);
539  m_pMb->buttonClicked().connect(SLOT(this, WsSiteMapView::doDelete));
540  m_pMb->show();
541 }
542 
543 void WsSiteMapView::doDelete(Wt::StandardButton button)
544 {
545  delete m_pMb;
546  if ( button != Wt::Ok ) return;
547  WModelIndexSet pSet = m_pTVView->selectedIndexes();
548  WModelIndexSet::iterator it = pSet.begin();
549  if ( pSet.empty() ) return;
550  WModelIndex idx = *it;
551  std::string str = asString(idx.data(UserRole)).toUTF8();
552  char type = str[0];
553  str.erase(0, 1);
554  try {
555  boost::filesystem::remove_all(str);
556  } catch (boost::filesystem::filesystem_error& e) {
557  std::cerr << e.what() << std::endl;
558  return;
559  }
560  fprintf(stderr, "delete item = %s\n", str.c_str());
561  m_pModelView->removeRow(idx.row(), idx.parent());
562  boost::filesystem::path newPath = str;
563  m_selectedDirectory = newPath.parent_path().string();
564  if ( m_tbFlags& gdWFileView::tbUseLeftTree && type == '1' ) {
565  //treeMatchPath(str);
566  pSet = m_pTVTree->selectedIndexes();
567  if ( !pSet.empty() ) {
568  it = pSet.begin();
569  WModelIndex idx = *it;
570  WsSiteMapItem* treeItem = dynamic_cast<WsSiteMapItem*>(m_pModelTree->itemFromIndex(idx));
571  treeItem->parent()->removeRow(treeItem->row());
572  //treeMatchPath(newPath.parent_path().string());
573  }
574  }
575 }
576 
578 {
579  boost::filesystem::path newPath = currentFolderPath() + "/NewFolder";
580  //loadFolder(m_pModelView->invisibleRootItem(), newPath, true);
581 }
582 
583 void WsSiteMapView::onDirectoryNameChanged(WStandardItem* pItem)
584 {
585  if ( pItem->index().column() != 0 ) return;
586  if ( m_bOnDataChanged ) return;
587  m_bOnDataChanged = true;
588  std::string newName = asString(pItem->data(EditRole)).toUTF8();
589  std::string oldPath = asString(pItem->data(UserRole)).toUTF8();
590  char type = oldPath[0];
591  oldPath.erase(0, 1);
592  pItem->setFlags(ItemIsSelectable);
593  std::string newPath = currentFolderPath() + "/" + newName;
594  pItem->setData(type + newPath, UserRole); // le path complet
595  m_bOnDataChanged = false;
596  bool bOnRename = m_bOnRename;
597  m_bOnRename = false;
598  if ( !bOnRename ) {
599  fprintf(stderr, "create new directory = %s\n", newPath.c_str());
600  try {
601  boost::filesystem::create_directory(newPath);
602  } catch (boost::filesystem::filesystem_error& e) {
603  std::cerr << e.what() << std::endl;
604  return;
605  }
606  } else {
607  fprintf(stderr, "Rename item = %s in %s\n", oldPath.c_str(), newPath.c_str());
608  try {
609  boost::filesystem::rename(oldPath, newPath);
610  } catch (boost::filesystem::filesystem_error& e) {
611  std::cerr << e.what() << std::endl;
612  return;
613  }
614  }
615  if ( type != '1' ) return;
616  WModelIndexSet pSet = m_pTVTree->selectedIndexes();
617  WModelIndexSet::iterator it = pSet.begin();
618  WsSiteMapItem* treeItem = dynamic_cast<WsSiteMapItem*>(m_pModelTree->invisibleRootItem());
619  if ( !pSet.empty() ) {
620  WModelIndex idx = *it;
621  WsSiteMapItem* treeItem = dynamic_cast<WsSiteMapItem*>(m_pModelTree->itemFromIndex(idx));
622  }
623  if ( !bOnRename );
624  //loadFolder(treeItem, newPath);
625  else {
626  oldPath = "1" + oldPath;
627  for (int iChild = 0; iChild < treeItem->rowCount(); ++iChild) {
628  std::string tvPath = asString(treeItem->child(iChild, 0)->data(UserRole)).toUTF8();
629  if ( tvPath == oldPath ) {
630  treeItem->child(iChild, 0)->setText(newName);
631  treeItem->setData(type + newPath, UserRole); // le path complet
632  }
633  }
634  }
635  treeItem->sortChildren(0, Wt::AscendingOrder);
636 }
637 
void onViewSelectionChanged()
void onViewDblClick(Wt::WModelIndex idx, Wt::WMouseEvent mouseEvent)
std::string m_selectedFile
NodePtr node()
void setCurrentPath(const std::string &currentPath)
boost::shared_ptr< WsAbstractNode > NodePtr
bool treeTraverse(Wt::WStandardItem *rootItem, const std::vector< std::string > &vPath, int nLevel)
void onViewExpanded(Wt::WModelIndex idx)
void setRelativePath(const std::string &relativePath)
virtual void load()
std::string m_sRootSiteMap
Wt::Signal< gdWFileView::signalType, std::string > & fileSelected()
Definition: WsSiteMapView.h:70
std::string SiteMapPath2path(const std::string &siteMapPath)
Wt::WStandardItemModel * m_pModelTree
Definition: WsSiteMapView.h:92
Wt::WTreeView * m_pTVTree
Definition: WsSiteMapView.h:94
std::string selectedPath()
Wt::WTreeView * m_pTVView
Definition: WsSiteMapView.h:95
NodePtr m_pTreecurNode
bool m_bOnDataChanged
Definition: WsSiteMapView.h:99
std::string currentFolderPath()
WsSiteMapView(gdwtcore::viewType dlgType, gdWFileView::tbFlags flags=gdWFileView::tbDefault, Wt::WContainerWidget *parent=0)
void init(NodePtr pNode)
std::string m_selectedDirectory
void onTreeExpanded(Wt::WModelIndex idx)
NodePtr m_node
Definition: WsSiteMapView.h:26
gdWFileView::tbFlags m_tbFlags
Definition: WsSiteMapView.h:91
Interface that provides differents methods for accessing the FsTree as well as other features...
Definition: WsUser.h:33
Wt::WStandardItemModel * m_pModelView
Definition: WsSiteMapView.h:93
void doDelete(Wt::StandardButton button)
bool loadTree(Wt::WStandardItem *currentItem, NodePtr pNode, gdWFileView::skipMode skipParentDir=gdWFileView::noSkipParent)
void onTreeSelectionChanged()
gdToolbarItem * m_tbiNewFolder
std::string selectedDirectory()
bool loadFile(Wt::WStandardItem *currentItem, const std::string &currentPath, NodePtr curNode)
void doConfirmDelete()
std::string path2SiteMapPath(const std::string &path)
void treeMatchPath(NodePtr pNode)
std::string m_sRootPath
bool isEditor()
Definition: WsUser.cpp:179
Wt::WMessageBox * m_pMb
gdToolbarItem * m_tbiDelete
const std::string getRootPath()
return the root path of the filesystem tree, example : /var/www/demo_site
Definition: WsUser.cpp:55
std::string get(const std::string &section, const std::string &id, const std::string &def)
bool loadFolder(Wt::WStandardItem *currentItem, const std::string &newPath, NodePtr curNode, bool bEdit=false)
#define WsApp
Define a shortcut to the application instance.
Definition: WsApplication.h:62
static WsLayoutProperties * instance()
Get the singleton instance.
void onDirectoryNameChanged(Wt::WStandardItem *pItem)
gdToolbar * m_pTb
Definition: WsSiteMapView.h:96
std::string selectedFile()
bool isAdministrator()
Definition: WsUser.cpp:184
NodePtr getAccessRoot()
return the root node of the access tree starting from the root
Definition: WsUser.cpp:50
std::string m_sSiteMap
void setNode(NodePtr pNode)
gdToolbarItem * m_tbiRename