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