16 #include <boost/algorithm/string/replace.hpp>
17 #include <boost/lexical_cast.hpp>
22 #include <Wt/WHBoxLayout>
23 #include <Wt/WVBoxLayout>
24 #include <Wt/WStandardItem>
26 #include <Wt/WStackedWidget>
27 #include <Wt/WItemDelegate>
30 #include <gdcore/gdCore.h>
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)
63 if ( WString::tr(
"byObjectStyleSheet").narrow() ==
"true" )
64 wApp->useStyleSheet(wApp->theme()->resourcesUrl() +
"wittyshare/Css/WsSiteMapView.css");
65 addStyleClass(
"WsSiteMapView");
68 wApp->messageResourceBundle().use(wApp->docRoot() + wApp->resourcesUrl() +
"wittyshare/Transl/WsSiteMapView");
69 if (
m_tbFlags == gdWFileView::tbDefault ) {
70 int nTmp = gdWFileView::tbDefault | gdWFileView::tbUseDummy;
73 setOverflow(WContainerWidget::OverflowHidden);
85 wApp->log(
"notice") <<
"WsSiteMapView::~WsSiteMapView()";
90 WContainerWidget::load();
92 m_pModelTree->setHeaderData(0, WString::tr(
"WsSiteMapView-Name"));
94 std::vector<WStandardItem*> pRow;
97 newItem->setIcon(wApp->theme()->resourcesUrl() +
"gdwtcore/Icons/folder.png");
98 pRow.push_back(newItem);
106 m_pTVTree->setSelectionMode(SingleSelection);
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"));
123 if (
m_tbFlags & gdWFileView::tbUseLeftTree )
127 m_pTVView->setColumnResizeEnabled(
true);
128 m_pTVView->setSortingEnabled(
true);
129 m_pTVView->setAlternatingRowColors(
true);
131 m_pTVView->setColumnWidth(1, 80);
132 m_pTVView->setColumnWidth(2, 80);
134 m_pTVView->setSelectionMode(ExtendedSelection);
135 m_pTVView->setColumnAlignment(1, AlignRight);
140 m_pTVView->setEditTriggers(WAbstractItemView::SingleClicked);
141 WItemDelegate* delegate =
new WItemDelegate(
this);
142 delegate->setTextFormat(
"%s");
143 m_pTVView->setItemDelegate(delegate);
146 WText* pTitle =
new WText(
"Site Map");
147 pTitle->addStyleClass(
"WsTitle");
148 WHBoxLayout* hbox =
new WHBoxLayout();
149 if (
m_tbFlags & gdWFileView::tbUseLeftTree )
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 ) {
158 vbox->addWidget(
m_pTb, 0);
160 vbox->addLayout(hbox, 1);
166 std::string str(path);
173 std::string str(siteMapPath);
180 if ( !loaded() )
load();
181 std::string str(relativePath);
182 boost::algorithm::replace_first(str,
m_sSiteMap,
"");
183 if ( str.size() < 1 )
188 wApp->root()->clear();
201 if (
m_tbFlags & gdWFileView::tbUseLeftTree )
204 wApp->log(
"error") <<
"WsSiteMapView::init() return with bad loadTree !!! ";
212 if ( nLevel >= vPath.size() )
return false;
213 for (
int nItem = 0; nItem < rootItem->rowCount(); ++nItem) {
215 std::string str = tmpItem->text().toUTF8();
216 if ( (vPath[nLevel]) == str )
217 if ( nLevel == vPath.size() - 1 ) {
232 if (pNode.get() == 0)
235 std::string myPath(pNode.get()->getPath().string());
237 std::vector<std::string> vPath;
240 if ( rootPath.size() < 1 )
242 vPath.push_back(rootPath);
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();
252 wApp->log(
"notice") <<
"WsSiteMapView::treeMatchPath() treetraverse ";
255 WModelIndexSet pSet =
m_pTVTree->selectedIndexes();
271 wApp->log(
"notice") <<
"WsSiteMapView::loadTree() m_pModelTree pNode full path = " << pNode.get()->getPath().string();
272 if ( pNode.get()->isDirectory() ) {
274 std::vector<WStandardItem*> pRow;
275 std::string newPath = pNode.get()->getPath().string();
278 newItem->setIcon(wApp->theme()->resourcesUrl() +
"gdwtcore/Icons/folder.png");
279 pRow.push_back(newItem);
282 currentItem->appendRow(pRow);
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) {
292 if ( curNode.get()->getProperties().get()->get(
"global",
"in_view",
"true") !=
"true" )
continue;
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;
300 if ( !
loadFile(currentItem, curPath, curNode) )
return false;
313 newItem->setData(
"1" + newPath, UserRole);
314 newItem->setIcon(wApp->theme()->resourcesUrl() +
"gdwtcore/Icons/folder.png");
316 currentItem->appendRow(newItem);
318 std::vector<WStandardItem*> pRow;
319 pRow.push_back(newItem);
322 currentItem->appendRow(pRow);
325 newItem->setFlags(ItemIsSelectable | ItemIsEditable);
331 if ( curNode.get()->getDirectories().size() == 0 )
return true;
333 if (
m_tbFlags & gdWFileView::tbUseDummy )
336 return loadTree(newItem, newItem->
node(), gdWFileView::noSkipParent);
338 if (
m_tbFlags & gdWFileView::tbUseLeftTree )
return true;
339 std::vector<WStandardItem*> pRowChild;
343 newItem->appendRow(pRowChild);
350 long fsize = curNode.get()->getSize();
351 std::string strSize = boost::lexical_cast<std::string>(fsize);
353 std::time_t t = curNode.get()->getModifyDate();
356 localtime_r(&t, &ttm);
357 strftime(c, 100,
"%Y-%m-%d", &ttm);
359 std::vector<WStandardItem*> pRow;
362 newItem->setData(
"2" + currentPath, UserRole);
364 newItem->setIcon(wApp->theme()->resourcesUrl() +
"gdwtcore/Icons/file.png");
365 pRow.push_back(newItem);
367 colSize->setData(fsize, UserRole);
368 pRow.push_back(colSize);
370 colDate->setData(strDate, UserRole);
371 pRow.push_back(colDate);
372 currentItem->appendRow(pRow);
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();
389 if (
m_tbFlags & gdWFileView::tbUseDummy )
390 if ( !
loadTree(pItem, pItem->
node(), gdWFileView::skipParent) )
return;
393 wApp->setInternalPath(str,
true);
399 if ( idx.column() != 0 )
return;
400 std::string str = asString(idx.data(UserRole)).toUTF8();
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);
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();
440 if ( idx.column() != 0 ) {
441 if ( idx.parent().isValid() )
442 idxcol0 = idx.parent().child(idx.row(), 0);
444 idxcol0 = idx.child(idx.row(), 0);
447 if ( !idxcol0.isValid() )
return;
448 std::string str = asString(idxcol0.data(UserRole)).toUTF8();
465 if ( idx.column() != 0 )
return;
466 std::string str = asString(idx.data(UserRole)).toUTF8();
472 pItem->removeRows(0, pItem->rowCount());
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());
509 m_tbiDelete =
m_pTb->addToolbarItem(wApp->theme()->resourcesUrl() +
"gdwtcore/Icons/Delete.png", WString::tr(
"WsSiteMapView-delete").toUTF8(), WString::tr(
"WsSiteMapView-delete-tooltips").toUTF8());
511 m_tbiRename =
m_pTb->addToolbarItem(wApp->theme()->resourcesUrl() +
"gdwtcore/Icons/rename.png", WString::tr(
"WsSiteMapView-rename").toUTF8(), WString::tr(
"WsSiteMapView-rename-tooltips").toUTF8());
517 WModelIndexSet pSet =
m_pTVView->selectedIndexes();
518 WModelIndexSet::iterator it = pSet.begin();
519 if ( pSet.empty() )
return;
520 WModelIndex idx = *it;
522 pItem->setFlags(ItemIsSelectable | ItemIsEditable);
523 WModelIndexSet pSet2;
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();
538 m_pMb =
new WMessageBox(
"Confirm",
"Remove " + str +
" ?", Wt::Question, Wt::Ok | Wt::Cancel);
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();
555 boost::filesystem::remove_all(str);
556 }
catch (boost::filesystem::filesystem_error& e) {
557 std::cerr << e.what() << std::endl;
560 fprintf(stderr,
"delete item = %s\n", str.c_str());
562 boost::filesystem::path newPath = str;
564 if (
m_tbFlags& gdWFileView::tbUseLeftTree && type ==
'1' ) {
567 if ( !pSet.empty() ) {
569 WModelIndex idx = *it;
571 treeItem->parent()->removeRow(treeItem->row());
585 if ( pItem->index().column() != 0 )
return;
588 std::string newName = asString(pItem->data(EditRole)).toUTF8();
589 std::string oldPath = asString(pItem->data(UserRole)).toUTF8();
590 char type = oldPath[0];
592 pItem->setFlags(ItemIsSelectable);
594 pItem->setData(type + newPath, UserRole);
599 fprintf(stderr,
"create new directory = %s\n", newPath.c_str());
601 boost::filesystem::create_directory(newPath);
602 }
catch (boost::filesystem::filesystem_error& e) {
603 std::cerr << e.what() << std::endl;
607 fprintf(stderr,
"Rename item = %s in %s\n", oldPath.c_str(), newPath.c_str());
609 boost::filesystem::rename(oldPath, newPath);
610 }
catch (boost::filesystem::filesystem_error& e) {
611 std::cerr << e.what() << std::endl;
615 if ( type !=
'1' )
return;
616 WModelIndexSet pSet =
m_pTVTree->selectedIndexes();
617 WModelIndexSet::iterator it = pSet.begin();
619 if ( !pSet.empty() ) {
620 WModelIndex idx = *it;
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);
635 treeItem->sortChildren(0, Wt::AscendingOrder);
void onViewSelectionChanged()
void onViewDblClick(Wt::WModelIndex idx, Wt::WMouseEvent mouseEvent)
std::string m_selectedFile
void setCurrentPath(const std::string ¤tPath)
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)
std::string m_sRootSiteMap
Wt::Signal< gdWFileView::signalType, std::string > & fileSelected()
std::string SiteMapPath2path(const std::string &siteMapPath)
Wt::WStandardItemModel * m_pModelTree
Wt::WTreeView * m_pTVTree
std::string selectedPath()
Wt::WTreeView * m_pTVView
std::string currentFolderPath()
WsSiteMapView(gdwtcore::viewType dlgType, gdWFileView::tbFlags flags=gdWFileView::tbDefault, Wt::WContainerWidget *parent=0)
std::string m_selectedDirectory
void onTreeExpanded(Wt::WModelIndex idx)
gdWFileView::tbFlags m_tbFlags
Interface that provides differents methods for accessing the FsTree as well as other features...
Wt::WStandardItemModel * m_pModelView
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 ¤tPath, NodePtr curNode)
std::string path2SiteMapPath(const std::string &path)
void treeMatchPath(NodePtr pNode)
gdToolbarItem * m_tbiDelete
const std::string getRootPath()
return the root path of the filesystem tree, example : /var/www/demo_site
std::string get(const std::string §ion, 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.
static WsLayoutProperties * instance()
Get the singleton instance.
void onDirectoryNameChanged(Wt::WStandardItem *pItem)
std::string selectedFile()
NodePtr getAccessRoot()
return the root node of the access tree starting from the root
void setNode(NodePtr pNode)
gdToolbarItem * m_tbiRename