11 #include <Wt/WApplication.h> 12 #include <Wt/WContainerWidget.h> 13 #include <Wt/WEnvironment.h> 14 #include <Wt/WLineEdit.h> 15 #include <Wt/WGridLayout.h> 16 #include <Wt/WHBoxLayout.h> 17 #include <Wt/WPushButton.h> 18 #include <Wt/WTable.h> 20 #include <Wt/WTreeView.h> 21 #include <Wt/WVBoxLayout.h> 22 #include <Wt/WViewWidget.h> 24 #include <boost/filesystem/operations.hpp> 25 #include <boost/filesystem/exception.hpp> 26 #include <boost/filesystem/convenience.hpp> 27 #include <boost/algorithm/string.hpp> 32 namespace fs = boost::filesystem;
37 #if BOOST_FILESYSTEM_VERSION < 3 38 return p.empty() ? std::string() : *--p.end();
40 return p.empty() ? std::string() : (*--p.end()).
string();
45 static std::string
stem(
const fs::path& p)
48 std::size_t pos = fn.find(
'.');
49 if (pos == std::string::npos)
52 return fn.substr(0, pos);
60 std::string path = p.string();
62 return path.substr(0, path.length() - fn.length() - 1);
71 const std::string& examplesRoot,
72 const std::string& examplesType)
73 : deployPath_(deployPath),
74 examplesRoot_(examplesRoot),
75 examplesType_(examplesType)
77 wApp->internalPathChanged().connect
90 if (example.find(
"..") != std::string::npos
91 || example.find(
'/') != std::string::npos
92 || example.find(
'\\') != std::string::npos) {
101 const std::string& example)
107 exists = fs::exists(exampleDir);
108 }
catch (std::exception&) {
112 WApplication::instance()->setInternalPathValid(
false);
113 addWidget(cpp14::make_unique<WText>(
"No such example: " + exampleDir));
117 model_ = std::make_shared<WStandardItemModel>(0, 1);
124 WApplication::instance()->setTitle(
tr(
"srcview.title." + example));
125 std::unique_ptr<WText> title(cpp14::make_unique<WText>(
127 title->setInternalPathEncoding(
true);
129 auto exampleView = cpp14::make_unique<WTreeView>();
132 exampleView_->resize(300, WLength::Auto);
133 exampleView_->setSortingEnabled(
false);
134 exampleView_->setModel(
model_);
135 exampleView_->expandToDepth(1);
136 exampleView_->setSelectionMode(SelectionMode::Single);
137 exampleView_->setAlternatingRowColors(
false);
138 exampleView_->selectionChanged().connect
153 exampleView_->setExpanded(w->
index(),
true);
157 exampleView_->select(w->
index());
162 auto topLayout = cpp14::make_unique<WVBoxLayout>();
163 topLayout->addWidget(std::move(title));
165 auto gitLayout = cpp14::make_unique<WHBoxLayout>();
167 gitLayout->
addWidget(std::move(exampleView), 0);
168 gitLayout->addWidget(std::move(sourceView), 1);
169 topLayout->addLayout(std::move(gitLayout), 1);
187 std::string ext = fs::extension(path);
191 else if (ext ==
".C" || ext ==
".cpp")
198 const fs::path& path)
200 static const char *supportedFiles[] = {
201 ".C",
".cpp",
".h",
".css",
".xml",
".png",
".gif",
".csv",
".ico", 0
204 auto dir = cpp14::make_unique<FileItem>(
"/icons/yellow-folder-open.png",
211 std::set<fs::path> paths;
213 fs::directory_iterator end_itr;
214 for (fs::directory_iterator i(path); i != end_itr; ++i)
217 std::vector<std::unique_ptr<FileItem>> classes, files;
218 std::vector<fs::path> dirs;
220 while (!paths.empty()) {
221 fs::path p = *paths.begin();
225 if (fs::is_symlink(p))
229 if (fs::is_regular(p)) {
230 std::string ext = fs::extension(p);
231 bool supported =
false;
232 for (
const char **s = supportedFiles; *s != 0; ++s)
244 if (!companion.empty()) {
245 std::set<fs::path>::iterator it_companion = paths.find(companion);
247 if (it_companion != paths.end()) {
248 std::string className =
stem(p);
249 escapeText(className);
250 std::string label =
"<i>class</i> " + className;
252 std::unique_ptr<FileItem> classItem =
253 cpp14::make_unique<FileItem>(
"/icons/cppclass.png", label, std::string());
257 = cpp14::make_unique<FileItem>(
"/icons/document.png",
filename(p),
260 = cpp14::make_unique<FileItem>(
"/icons/document.png",
262 (*it_companion).string());
263 classItem->appendRow(std::move(header));
264 classItem->appendRow(std::move(cpp));
266 classes.push_back(std::move(classItem));
267 paths.erase(it_companion);
270 = cpp14::make_unique<FileItem>(
"/icons/document.png",
filename(p),
272 files.push_back(std::move(file));
274 }
else if (fs::is_directory(p)) {
278 = cpp14::make_unique<FileItem>(
"/icons/document.png",
filename(p),
280 files.push_back(std::move(file));
286 for (
unsigned int i = 0; i < classes.size(); i++)
287 parent->
appendRow(std::move(classes[i]));
289 for (
unsigned int i = 0; i < files.size(); i++)
292 for (
unsigned int i = 0; i < dirs.size(); i++)
294 }
catch (fs::filesystem_error& e) {
295 std::cerr << e.what() << std::endl;
300 const fs::path& srcPath,
301 const std::string packageName)
303 fs::directory_iterator end_itr;
306 for (fs::directory_iterator i(srcPath); i != end_itr; ++i) {
308 if (fs::is_regular(p)) {
310 auto item = cpp14::make_unique<FileItem>(
"/icons/package.png", packageName,
"");
311 packageItem = item.get();
316 = cpp14::make_unique<FileItem>(
"/icons/javaclass.png",
filename(p),
322 for (fs::directory_iterator i(srcPath); i != end_itr; ++i) {
324 if (fs::is_directory(p)) {
325 std::string pn = packageName;
336 const fs::path& path)
339 = cpp14::make_unique<FileItem>(
"/icons/yellow-folder-open.png",
345 std::vector<fs::path> files, dirs;
347 fs::directory_iterator end_itr;
348 for (fs::directory_iterator i(path); i != end_itr; ++i) {
350 if (fs::is_directory(p)) {
353 = cpp14::make_unique<FileItem>(
"/icons/package-folder-open.png",
368 for (
auto item : dirs)
371 for (
auto item : files) {
373 = cpp14::make_unique<FileItem>(
"/icons/document.png",
filename(item),
static std::string stem(const fs::path &p)
bool internalPathMatches(const std::string &path) const
static const Wt::ItemDataRole FileNameRole
void javaTraversePackages(WStandardItem *parent, const boost::filesystem::path &srcPath, const std::string packageName)
WStandardItem which stores a file.
void cppTraverseDir(WStandardItem *parent, const boost::filesystem::path &path)
WModelIndexSet selectedIndexes() const
void showFile()
Displayed the currently selected file.
void setExample(const std::string &exampleDir, const std::string &example)
void javaTraverseDir(WStandardItem *parent, const boost::filesystem::path &path)
WStandardItem * child(int row, int column=0) const
void addWidget(std::unique_ptr< WWidget > widget, int stretch, WFlags< AlignmentFlag > alignment)
void setInternalPathValid(bool valid)
std::string examplesRoot_
virtual void setHeaderHeight(const WLength &height) override
std::string internalPathNextPart(const std::string &path) const
std::shared_ptr< WStandardItemModel > model_
WModelIndex index() const
std::shared_ptr< WAbstractItemModel > model() const
bool setIndex(const WModelIndex &index)
Sets the model index.
bool isExpanded(const WModelIndex &index) const
ExampleSourceViewer(const std::string &deployPath, const std::string &examplesRoot, const std::string &examplesType)
Constructor.
std::string examplesType_
static std::string filename(const fs::path &p)
void setExpanded(const WModelIndex &, bool expanded)
static bool comparePaths(const fs::path &p1, const fs::path &p2)
void appendRow(std::vector< std::unique_ptr< WStandardItem >> items)
static const Wt::ItemDataRole ContentsRole
static const Wt::ItemDataRole FilePathRole
fs::path parent_path(const fs::path &p)
static fs::path getCompanion(const fs::path &path)