1 | #include <Wt/WVBoxLayout> |
---|
2 | #include <Wt/WHBoxLayout> |
---|
3 | #include <Wt/WImage> |
---|
4 | #include <Wt/WText> |
---|
5 | #include <Wt/WBreak> |
---|
6 | #include <Wt/WHBoxLayout> |
---|
7 | #include <Wt/WPushButton> |
---|
8 | #include <Wt/WCssDecorationStyle> |
---|
9 | #include <Wt/WTree> |
---|
10 | #include <Wt/WTreeNode> |
---|
11 | #include <Wt/WIconPair> |
---|
12 | #include <Wt/WApplication> |
---|
13 | |
---|
14 | |
---|
15 | #include <boost/algorithm/string.hpp> |
---|
16 | #include <dirent.h> /* readdir(), etc. */ |
---|
17 | #include <sys/stat.h> /* stat(), etc. */ |
---|
18 | |
---|
19 | #include "GWt_serverFileSelector.h" |
---|
20 | |
---|
21 | |
---|
22 | GWt_serverFileSelector::GWt_serverFileSelector( |
---|
23 | WString titre, |
---|
24 | std::string wd): |
---|
25 | GWt_dialog(titre, NULL, true) |
---|
26 | { |
---|
27 | |
---|
28 | workingDir_ = wd; |
---|
29 | |
---|
30 | Wt::WIconPair *folderIcon = new Wt::WIconPair("htdocs/yellow-folder-closed.png", |
---|
31 | "htdocs/yellow-folder-open.png", false); |
---|
32 | |
---|
33 | treeRoot_ = new Wt::WTree(); |
---|
34 | treeRoot_->setSelectionMode(Wt::SingleSelection); |
---|
35 | |
---|
36 | /* this structure is used for storing the name of each entry in turn. */ |
---|
37 | struct dirent* entry; |
---|
38 | |
---|
39 | /* read the directory's contents, print out the name of each entry. */ |
---|
40 | DIR* dir = opendir(workingDir_.c_str()); |
---|
41 | if (!dir) { |
---|
42 | exit(1); |
---|
43 | } |
---|
44 | struct stat dir_stat; /* used by stat(). */ |
---|
45 | while ( (entry = readdir(dir)) != NULL) { |
---|
46 | /* check if the given entry is a directory. */ |
---|
47 | if (stat(entry->d_name, &dir_stat) == -1) { |
---|
48 | continue; |
---|
49 | } |
---|
50 | } |
---|
51 | |
---|
52 | |
---|
53 | Wt::WTreeNode* treeFileRoot = new Wt::WTreeNode("Workspace", folderIcon); |
---|
54 | |
---|
55 | // treeFileRoot->setStyleClass("example-tree"); |
---|
56 | treeRoot_->setTreeRoot(treeFileRoot); |
---|
57 | treeFileRoot->label()->setTextFormat(Wt::PlainText); |
---|
58 | treeFileRoot->setImagePack("resources/"); |
---|
59 | treeFileRoot->setLoadPolicy(Wt::WTreeNode::NextLevelLoading); |
---|
60 | |
---|
61 | buildConfigurationFileTree(treeFileRoot, workingDir_.c_str(), ".save"); |
---|
62 | |
---|
63 | // Add user files |
---|
64 | Wt::WTreeNode* userTreeFileRoot = new Wt::WTreeNode("MySession", folderIcon); |
---|
65 | buildConfigurationFileTree(treeFileRoot, (workingDir_+WApplication::instance()->sessionId()).c_str(), ".save"); |
---|
66 | |
---|
67 | treeFileRoot->expand(); |
---|
68 | WContainerWidget *treeContainer = new WContainerWidget(); |
---|
69 | treeContainer->addWidget(treeRoot_); |
---|
70 | |
---|
71 | WContainerWidget *buttonContainer = new WContainerWidget(); |
---|
72 | WHBoxLayout* hButtonLayout = new WHBoxLayout(); |
---|
73 | |
---|
74 | WPushButton *annule = new WPushButton("cancel"); |
---|
75 | WPushButton *submit = new WPushButton("OK"); |
---|
76 | hButtonLayout->addWidget(annule); |
---|
77 | hButtonLayout->addWidget(submit); |
---|
78 | |
---|
79 | annule->clicked().connect(this, &Wt::WDialog::reject); |
---|
80 | submit->clicked().connect(this, &Wt::WDialog::accept); |
---|
81 | |
---|
82 | buttonContainer->setLayout(hButtonLayout); |
---|
83 | |
---|
84 | // add the container already present |
---|
85 | |
---|
86 | addVContent(treeContainer); |
---|
87 | addVContent(buttonContainer); |
---|
88 | |
---|
89 | treeContainer->resize(400,300); |
---|
90 | treeContainer->setOverflow(WContainerWidget::OverflowAuto); |
---|
91 | |
---|
92 | } |
---|
93 | |
---|
94 | |
---|
95 | |
---|
96 | /* |
---|
97 | * function: findfile. recusively traverse the current directory, searching |
---|
98 | * for files with a given string in their name. |
---|
99 | * input: string to match. |
---|
100 | * output: any file found, printed to the screen with a full path. |
---|
101 | */ |
---|
102 | void GWt_serverFileSelector::buildConfigurationFileTree(Wt::WTreeNode *treeFileRoot, const char* folder, const char* pattern) |
---|
103 | { |
---|
104 | #define MAX_DIR_PATH 2048 /* maximal full path we support. */ |
---|
105 | |
---|
106 | DIR* dir; /* pointer to the scanned directory. */ |
---|
107 | struct dirent* entry; /* pointer to one directory entry. */ |
---|
108 | char cwd[MAX_DIR_PATH+1]; /* current working directory. */ |
---|
109 | struct stat dir_stat; /* used by stat(). */ |
---|
110 | |
---|
111 | /* first, save path of current working directory */ |
---|
112 | if (!getcwd(cwd, MAX_DIR_PATH+1)) { |
---|
113 | return; |
---|
114 | } |
---|
115 | |
---|
116 | |
---|
117 | /* open the directory for reading */ |
---|
118 | dir = opendir(folder); |
---|
119 | if (!dir) { |
---|
120 | return; |
---|
121 | } |
---|
122 | |
---|
123 | /* scan the directory, traversing each sub-directory, and */ |
---|
124 | /* matching the pattern for each file name. */ |
---|
125 | while ((entry = readdir(dir))) { |
---|
126 | |
---|
127 | /* skip the "." and ".." entries, to avoid loops. */ |
---|
128 | if (strcmp(entry->d_name, ".") == 0) |
---|
129 | continue; |
---|
130 | if (strcmp(entry->d_name, "..") == 0) |
---|
131 | continue; |
---|
132 | if (strcmp(entry->d_name, ".svn") == 0) |
---|
133 | continue; |
---|
134 | /* check if the given entry is a directory. */ |
---|
135 | if (entry->d_type == DT_DIR) { |
---|
136 | Wt::WIconPair *folderIcon = new Wt::WIconPair("htdocs/yellow-folder-closed.png", |
---|
137 | "htdocs/yellow-folder-open.png", false); |
---|
138 | Wt::WTreeNode *child = new Wt::WTreeNode(entry->d_name, folderIcon); |
---|
139 | treeFileRoot->addChildNode(child); |
---|
140 | buildConfigurationFileTree(child,(std::string(folder)+entry->d_name).c_str(), pattern); |
---|
141 | |
---|
142 | } else { |
---|
143 | |
---|
144 | /* check if the pattern matchs. */ |
---|
145 | if (boost::algorithm::ends_with(entry->d_name, pattern)) { |
---|
146 | treeFileRoot->addChildNode(new Wt::WTreeNode(entry->d_name)); |
---|
147 | } |
---|
148 | } |
---|
149 | } |
---|
150 | } |
---|
151 | |
---|
152 | std::string GWt_serverFileSelector::exec() { |
---|
153 | |
---|
154 | Wt::WDialog::DialogCode dc = WDialog::exec(); |
---|
155 | if (dc == Rejected) { |
---|
156 | return ""; |
---|
157 | } |
---|
158 | const Wt::WTree::WTreeNodeSet& tr = treeRoot_->selectedNodes(); |
---|
159 | if (tr.empty()) { |
---|
160 | return ""; |
---|
161 | } |
---|
162 | std::string path = (*tr.begin())->label()->text().toUTF8(); |
---|
163 | |
---|
164 | Wt::WTreeNode* parent = (*tr.begin())->parentNode(); |
---|
165 | while (parent) { |
---|
166 | parent = parent->parentNode(); |
---|
167 | if( parent) { |
---|
168 | path = parent->label()->text().toUTF8()+"/"+path; |
---|
169 | } |
---|
170 | } |
---|
171 | return workingDir_+path; |
---|
172 | } |
---|