00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.hpp"
00016
00017 #define GETTEXT_DOMAIN "wesnoth-lib"
00018
00019 #include "display.hpp"
00020 #include "events.hpp"
00021 #include "filesystem.hpp"
00022 #include "gettext.hpp"
00023 #include "key.hpp"
00024 #include "marked-up_text.hpp"
00025 #include "show_dialog.hpp"
00026 #include "wml_separators.hpp"
00027 #include "widgets/file_menu.hpp"
00028
00029 #include <sstream>
00030 #include <cstdio>
00031
00032 namespace {
00033 std::vector<std::string> empty_string_vector;
00034 }
00035
00036 namespace gui {
00037
00038 static const std::string dir_picture("misc/folder-icon.png");
00039 static const std::string path_up("..");
00040 const char file_menu::path_delim('/');
00041
00042 file_menu::file_menu(CVideo &disp, std::string start_file)
00043 : menu(disp, empty_string_vector, false),
00044 current_dir_(get_path(start_file)),
00045 chosen_file_(start_file), last_selection_(-1)
00046 {
00047
00048 if((!file_exists(chosen_file_) && !::is_directory(chosen_file_))
00049 || !::is_directory(current_dir_)) {
00050 current_dir_ = path_delim;
00051 chosen_file_ = current_dir_;
00052 }
00053
00054
00055
00056
00057
00058 update_file_lists();
00059 }
00060
00061 void file_menu::display_current_files() {
00062 std::vector<std::string> to_show;
00063 if (!is_root(current_dir_)) {
00064 to_show.push_back(path_up);
00065 }
00066 std::vector<std::string>::iterator it;
00067 for (it = dirs_in_current_dir_.begin(); it != dirs_in_current_dir_.end(); it++) {
00068
00069 std::stringstream ss;
00070 ss << font::IMAGE << dir_picture << COLUMN_SEPARATOR << *it;
00071 to_show.push_back(ss.str());
00072 }
00073 for (it = files_in_current_dir_.begin(); it != files_in_current_dir_.end(); it++) {
00074 const std::string display_string = COLUMN_SEPARATOR + *it;
00075 to_show.push_back(display_string);
00076 }
00077 const int menu_font_size = font::SIZE_NORMAL;
00078 for (it = to_show.begin(); it != to_show.end(); it++) {
00079
00080
00081
00082 while(static_cast<unsigned int>(
00083 font::line_width(*it, menu_font_size)) > width() - 30 - 25) {
00084
00085 (*it).resize((*it).size() - 1);
00086 }
00087 }
00088 set_items(to_show);
00089 }
00090
00091 int file_menu::delete_chosen_file() {
00092 const int ret = remove(chosen_file_.c_str());
00093 if (ret == -1) {
00094
00095 }
00096 else {
00097 last_selection_ = -1;
00098 update_file_lists();
00099 chosen_file_ = current_dir_;
00100 }
00101 return ret;
00102 }
00103
00104 bool file_menu::make_directory(const std::string& subdir_name) {
00105 bool ret = ::make_directory(add_path(current_dir_, subdir_name));
00106 if (ret == false) {
00107
00108 }
00109 else {
00110 last_selection_ = -1;
00111 update_file_lists();
00112 chosen_file_ = current_dir_;
00113 }
00114 return ret;
00115 }
00116
00117 void file_menu::handle_event(const SDL_Event& event) {
00118 menu::handle_event(event);
00119 if(selection() != last_selection_) {
00120 entry_selected(selection());
00121 last_selection_ = selection();
00122 }
00123 }
00124
00125 void file_menu::entry_selected(const unsigned entry) {
00126 const int entry_index = entry - (is_root(current_dir_) ? 0 : 1);
00127 if (entry_index >= 0) {
00128 std::string selected;
00129 if(static_cast<unsigned>(entry_index) < dirs_in_current_dir_.size()) {
00130 const int dir_index = entry_index;
00131 selected = dirs_in_current_dir_[dir_index];
00132 }
00133 else {
00134 const int file_index = entry_index - dirs_in_current_dir_.size();
00135 if(file_index >= 0 && size_t(file_index) < files_in_current_dir_.size()) {
00136 selected = files_in_current_dir_[file_index];
00137 } else {
00138 return;
00139 }
00140 }
00141 chosen_file_ = add_path(current_dir_, selected);
00142 } else {
00143 chosen_file_ = path_up;
00144 }
00145 }
00146
00147 bool file_menu::is_directory(const std::string& fname) const {
00148 if(fname == path_up)
00149 return true;
00150 return ::is_directory(fname);
00151 }
00152
00153 void file_menu::change_directory(const std::string path) {
00154 if(path == path_up)
00155 {
00156
00157 if (!is_root(current_dir_)) {
00158 current_dir_ = get_path_up(current_dir_);
00159 last_selection_ = -1;
00160 update_file_lists();
00161 chosen_file_ = current_dir_;
00162 }
00163 else {
00164 return;
00165 }
00166
00167 } else {
00168 current_dir_ = path;
00169 chosen_file_ = current_dir_;
00170 last_selection_ = -1;
00171 update_file_lists();
00172 }
00173 }
00174
00175 std::string file_menu::get_choice() const {
00176 return chosen_file_;
00177 }
00178
00179
00180 std::string file_menu::get_path(const std::string file_or_dir) const {
00181 std::string res_path = file_or_dir;
00182 if (!::is_directory(file_or_dir)) {
00183 size_t index = file_or_dir.find_last_of(path_delim);
00184 if (index != std::string::npos) {
00185 res_path = file_or_dir.substr(0, index);
00186 }
00187 }
00188 return res_path;
00189 }
00190
00191 std::string file_menu::get_path_up(const std::string path, const unsigned levels) const {
00192 std::string curr_path = get_path(path);
00193 for (unsigned i = 0; i < levels; i++) {
00194 if (is_root(curr_path)) {
00195 break;
00196 }
00197 curr_path = strip_last_delim(curr_path);
00198 size_t index = curr_path.find_last_of(path_delim);
00199 if (index != std::string::npos) {
00200 curr_path = curr_path.substr(0, index);
00201 }
00202 else {
00203 #ifdef __AMIGAOS4__
00204 index = curr_path.find_last_of(':');
00205 if (index != std::string::npos) index++;
00206 #endif
00207 break;
00208 }
00209 }
00210 if (curr_path.size() == 0) {
00211
00212 curr_path = path_delim;
00213 }
00214 return curr_path;
00215 }
00216
00217 std::string file_menu::strip_last_delim(const std::string path) const {
00218 std::string res_string = path;
00219 if (path[path.size() - 1] == path_delim) {
00220 res_string = path.substr(0, path.size() - 1);
00221 }
00222 return res_string;
00223 }
00224
00225 bool file_menu::is_root(const std::string path) const {
00226 #ifdef __AMIGAOS4__
00227 return path.size() == 0 || path[path.size()-1] == ':';
00228 #else
00229 return path.size() == 0 || (path.size() == 1 && path[0] == path_delim);
00230 #endif
00231 }
00232
00233 std::string file_menu::add_path(const std::string path, const std::string to_add) const
00234 {
00235 std::string joined_path = strip_last_delim(path);
00236 if (to_add.size() > 0) {
00237 if (to_add == path_up) {
00238 return get_path_up(path);
00239 }
00240 #ifdef __AMIGAOS4__
00241 else if (joined_path.empty() || joined_path[joined_path.size()-1] == ':') {
00242 if (to_add[0] == path_delim)
00243 joined_path += to_add.substr(1);
00244 else
00245 joined_path += to_add;
00246 }
00247 #endif
00248 else if (to_add[0] == path_delim) {
00249 joined_path += to_add;
00250 }
00251 else {
00252 joined_path += "/" + to_add;
00253 }
00254 }
00255 return joined_path;
00256 }
00257
00258 void file_menu::update_file_lists() {
00259 files_in_current_dir_.clear();
00260 dirs_in_current_dir_.clear();
00261 get_files_in_dir(current_dir_, &files_in_current_dir_,
00262 &dirs_in_current_dir_, FILE_NAME_ONLY);
00263 display_current_files();
00264 }
00265
00266 }