added permission error messsage, fix pane line, add root message if running as root
This commit is contained in:
@@ -42,6 +42,7 @@ enum {
|
|||||||
CP_OVERLAY_TITLE,
|
CP_OVERLAY_TITLE,
|
||||||
CP_BUTTON_YES,
|
CP_BUTTON_YES,
|
||||||
CP_BUTTON_NO,
|
CP_BUTTON_NO,
|
||||||
|
CP_ROOT_WARN,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ATTR_DIR (COLOR_PAIR(CP_DIR) | A_BOLD)
|
#define ATTR_DIR (COLOR_PAIR(CP_DIR) | A_BOLD)
|
||||||
@@ -54,6 +55,7 @@ enum {
|
|||||||
#define ATTR_MARKER COLOR_PAIR(CP_MARKER)
|
#define ATTR_MARKER COLOR_PAIR(CP_MARKER)
|
||||||
#define ATTR_INFO COLOR_PAIR(CP_INFO)
|
#define ATTR_INFO COLOR_PAIR(CP_INFO)
|
||||||
#define ATTR_OVERLAY_BORDER COLOR_PAIR(CP_OVERLAY_BORDER)
|
#define ATTR_OVERLAY_BORDER COLOR_PAIR(CP_OVERLAY_BORDER)
|
||||||
|
#define ATTR_ROOT_WARN (COLOR_PAIR(CP_ROOT_WARN) | A_BOLD)
|
||||||
|
|
||||||
// ─── Entry data ─────────────────────────────────────────────────────────────
|
// ─── Entry data ─────────────────────────────────────────────────────────────
|
||||||
enum class EntryType { Directory, File, Symlink };
|
enum class EntryType { Directory, File, Symlink };
|
||||||
@@ -154,6 +156,7 @@ private:
|
|||||||
bool show_details_ = false;
|
bool show_details_ = false;
|
||||||
bool show_preview_ = false;
|
bool show_preview_ = false;
|
||||||
bool searching_ = false;
|
bool searching_ = false;
|
||||||
|
bool is_root_ = false;
|
||||||
std::string filter_;
|
std::string filter_;
|
||||||
std::string info_msg_;
|
std::string info_msg_;
|
||||||
|
|
||||||
@@ -321,6 +324,7 @@ void FileManager::init_colors() {
|
|||||||
init_pair(CP_OVERLAY_TITLE, COLOR_CYAN, -1);
|
init_pair(CP_OVERLAY_TITLE, COLOR_CYAN, -1);
|
||||||
init_pair(CP_BUTTON_YES, COLOR_GREEN, -1);
|
init_pair(CP_BUTTON_YES, COLOR_GREEN, -1);
|
||||||
init_pair(CP_BUTTON_NO, COLOR_RED, -1);
|
init_pair(CP_BUTTON_NO, COLOR_RED, -1);
|
||||||
|
init_pair(CP_ROOT_WARN, COLOR_RED, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── directory loading ──────────────────────────────────────────────────────
|
// ─── directory loading ──────────────────────────────────────────────────────
|
||||||
@@ -554,13 +558,22 @@ void FileManager::draw_botbar() {
|
|||||||
right = " press ? for help ";
|
right = " press ? for help ";
|
||||||
}
|
}
|
||||||
|
|
||||||
int total = static_cast<int>(left.size() + right.size());
|
std::string root_tag = is_root_ ? "[root] " : "";
|
||||||
|
int total = static_cast<int>(root_tag.size() + left.size() + right.size());
|
||||||
int pad = cols_ - total;
|
int pad = cols_ - total;
|
||||||
if (pad < 0) pad = 0;
|
if (pad < 0) pad = 0;
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
if (is_root_) {
|
||||||
|
attron(ATTR_ROOT_WARN);
|
||||||
|
mvprintw(rows_ - 1, 0, "%s", root_tag.c_str());
|
||||||
|
attroff(ATTR_ROOT_WARN);
|
||||||
|
x = static_cast<int>(root_tag.size());
|
||||||
|
}
|
||||||
|
|
||||||
attron(ATTR_TOPBAR);
|
attron(ATTR_TOPBAR);
|
||||||
mvprintw(rows_ - 1, 0, "%s", left.c_str());
|
mvprintw(rows_ - 1, x, "%s", left.c_str());
|
||||||
for (int i = 0; i < pad; ++i) mvaddch(rows_ - 1, static_cast<int>(left.size()) + i, ' ');
|
for (int i = 0; i < pad; ++i) mvaddch(rows_ - 1, x + static_cast<int>(left.size()) + i, ' ');
|
||||||
attroff(ATTR_TOPBAR);
|
attroff(ATTR_TOPBAR);
|
||||||
|
|
||||||
attron(ATTR_INFO);
|
attron(ATTR_INFO);
|
||||||
@@ -711,11 +724,10 @@ void FileManager::draw_preview() {
|
|||||||
if (!e) return;
|
if (!e) return;
|
||||||
|
|
||||||
// Draw vertical divider
|
// Draw vertical divider
|
||||||
for (int r = 1; r < rows_ - 1; ++r) {
|
|
||||||
attron(ATTR_DIVIDER);
|
attron(ATTR_DIVIDER);
|
||||||
mvaddch(r, list_cols_, '|');
|
for (int r = 1; r < rows_ - 1; ++r)
|
||||||
|
mvaddch(r, list_cols_, ACS_VLINE);
|
||||||
attroff(ATTR_DIVIDER);
|
attroff(ATTR_DIVIDER);
|
||||||
}
|
|
||||||
|
|
||||||
// Clear entire preview area of previous content (stale lines from last preview)
|
// Clear entire preview area of previous content (stale lines from last preview)
|
||||||
for (int r = 1; r < rows_ - 1; ++r) {
|
for (int r = 1; r < rows_ - 1; ++r) {
|
||||||
@@ -1598,6 +1610,12 @@ void FileManager::do_help() {
|
|||||||
void FileManager::do_rename() {
|
void FileManager::do_rename() {
|
||||||
const Entry *e = get_sel();
|
const Entry *e = get_sel();
|
||||||
if (!e) return;
|
if (!e) return;
|
||||||
|
|
||||||
|
if (access(cwd_.c_str(), W_OK) != 0) {
|
||||||
|
flash_msg("permission denied: " + cwd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Strip trailing / or @
|
// Strip trailing / or @
|
||||||
std::string name = e->name;
|
std::string name = e->name;
|
||||||
if (!name.empty() && (name.back() == '/' || name.back() == '@'))
|
if (!name.empty() && (name.back() == '/' || name.back() == '@'))
|
||||||
@@ -1612,11 +1630,16 @@ void FileManager::do_rename() {
|
|||||||
if (std::rename(src.c_str(), dst.c_str()) == 0) {
|
if (std::rename(src.c_str(), dst.c_str()) == 0) {
|
||||||
load_entries();
|
load_entries();
|
||||||
} else {
|
} else {
|
||||||
flash_msg("rename failed");
|
flash_msg("rename failed: " + std::string(std::strerror(errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager::do_mkdir() {
|
void FileManager::do_mkdir() {
|
||||||
|
if (access(cwd_.c_str(), W_OK) != 0) {
|
||||||
|
flash_msg("permission denied: " + cwd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
if (!read_line(name, " Directory name: ")) { need_full_redraw_ = true; return; }
|
if (!read_line(name, " Directory name: ")) { need_full_redraw_ = true; return; }
|
||||||
if (name.empty()) { flash_msg("cancelled"); return; }
|
if (name.empty()) { flash_msg("cancelled"); return; }
|
||||||
@@ -1625,11 +1648,16 @@ void FileManager::do_mkdir() {
|
|||||||
if (fs::create_directory(path)) {
|
if (fs::create_directory(path)) {
|
||||||
load_entries();
|
load_entries();
|
||||||
} else {
|
} else {
|
||||||
flash_msg("mkdir failed");
|
flash_msg("mkdir failed: " + std::string(std::strerror(errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager::do_newfile() {
|
void FileManager::do_newfile() {
|
||||||
|
if (access(cwd_.c_str(), W_OK) != 0) {
|
||||||
|
flash_msg("permission denied: " + cwd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
if (!read_line(name, " File name: ")) { need_full_redraw_ = true; return; }
|
if (!read_line(name, " File name: ")) { need_full_redraw_ = true; return; }
|
||||||
if (name.empty()) { flash_msg("cancelled"); return; }
|
if (name.empty()) { flash_msg("cancelled"); return; }
|
||||||
@@ -1640,11 +1668,16 @@ void FileManager::do_newfile() {
|
|||||||
f.close();
|
f.close();
|
||||||
load_entries();
|
load_entries();
|
||||||
} else {
|
} else {
|
||||||
flash_msg("cannot create file");
|
flash_msg("cannot create file: " + std::string(std::strerror(errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager::do_delete() {
|
void FileManager::do_delete() {
|
||||||
|
if (access(cwd_.c_str(), W_OK) != 0) {
|
||||||
|
flash_msg("permission denied: " + cwd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Gather items to delete
|
// Gather items to delete
|
||||||
std::vector<std::string> targets;
|
std::vector<std::string> targets;
|
||||||
if (!selected_.empty()) {
|
if (!selected_.empty()) {
|
||||||
@@ -1709,6 +1742,12 @@ void FileManager::do_delete() {
|
|||||||
void FileManager::do_trash() {
|
void FileManager::do_trash() {
|
||||||
const Entry *e = get_sel();
|
const Entry *e = get_sel();
|
||||||
if (!e) return;
|
if (!e) return;
|
||||||
|
|
||||||
|
if (access(cwd_.c_str(), W_OK) != 0) {
|
||||||
|
flash_msg("permission denied: " + cwd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string name = e->name;
|
std::string name = e->name;
|
||||||
if (!name.empty() && name.back() == '/') name.pop_back();
|
if (!name.empty() && name.back() == '/') name.pop_back();
|
||||||
if (!name.empty() && name.back() == '@') name.pop_back();
|
if (!name.empty() && name.back() == '@') name.pop_back();
|
||||||
@@ -1743,7 +1782,7 @@ void FileManager::do_trash() {
|
|||||||
sel_ = std::max(0, static_cast<int>(entries_.size()) - 2);
|
sel_ = std::max(0, static_cast<int>(entries_.size()) - 2);
|
||||||
load_entries();
|
load_entries();
|
||||||
} else {
|
} else {
|
||||||
flash_msg("trash failed");
|
flash_msg("trash failed: " + std::string(std::strerror(errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1805,7 +1844,7 @@ void FileManager::do_chmod_x(bool set) {
|
|||||||
flash_msg(set ? "chmod +x: " + e->name : "chmod -x: " + e->name);
|
flash_msg(set ? "chmod +x: " + e->name : "chmod -x: " + e->name);
|
||||||
load_entries();
|
load_entries();
|
||||||
} else {
|
} else {
|
||||||
flash_msg("chmod failed");
|
flash_msg("chmod failed: " + std::string(std::strerror(errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2021,6 +2060,11 @@ void FileManager::do_paste() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (access(cwd_.c_str(), W_OK) != 0) {
|
||||||
|
flash_msg("permission denied: " + cwd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &src : clipboard_paths_) {
|
for (const auto &src : clipboard_paths_) {
|
||||||
std::string name = fs::path(src).filename().string();
|
std::string name = fs::path(src).filename().string();
|
||||||
std::string dst = join_path(cwd_, name);
|
std::string dst = join_path(cwd_, name);
|
||||||
@@ -2291,6 +2335,8 @@ void FileManager::run() {
|
|||||||
if (can_color()) init_colors();
|
if (can_color()) init_colors();
|
||||||
load_entries();
|
load_entries();
|
||||||
|
|
||||||
|
is_root_ = (geteuid() == 0);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
draw();
|
draw();
|
||||||
int key = getch();
|
int key = getch();
|
||||||
|
|||||||
Reference in New Issue
Block a user