Files
pip/utils/system_daemon/file_manager.cpp
Пелипенко Иван fce75cb88f pisdr windows drives support
git-svn-id: svn://db.shs.com.ru/pip@57 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
2015-04-01 11:58:17 +00:00

399 lines
10 KiB
C++

#include "file_manager.h"
#include "shared.h"
#include "daemon.h"
extern PIScreen screen;
FileManager::TileDir::TileDir(): TileList() {
label_path = 0;
selection_mode = TileList::MultiSelection;
dir = PIDir::current();
resized = remote = false;
}
bool FileManager::TileDir::keyEvent(PIKbdListener::KeyEvent key) {
bool pass = false;
PIString nd;
switch (key.key) {
case 'R': if (!remote) updateDir(); pass = true; break;
case PIKbdListener::F7:
nd = askNewDir();
setFocus();
if (nd.isEmpty()) return true;
if (!remote) {
PIDir::make(dir.absolutePath() + PIDir::separator + nd);
updateDir();
}
pass = true;
break;
case PIKbdListener::F8:
if (selected.isEmpty())
selected << cur;
if (!askQuestion("Delete selected?")) return false;
setFocus();
if (!remote) {
PIStringList sl;
PIVector<int> sind = selected.toVector();
piForeachC (int i, sind)
sl << entries[i].name();
removeFiles(dir, sl);
updateDir();
}
pass = true;
break;
case PIKbdListener::Return:
if (cur < entries.size_s() && cur >= 0) {
if (!remote) {
//piCout << entries[cur];
if (entries[cur].isDir()) {
prev_pos[dir.path()] = PIPair<int, int>(cur, offset);
dir.cd(entries[cur].name());
PIPair<int, int> cp = prev_pos.value(dir.path());
cur = cp.first;
offset = cp.second;
selected.clear();
updateDir();
}
}
pass = true;
}
break;
}
if (remote && pass) {
((void(*)(void*,PIKbdListener::KeyEvent))key_func)(fm, key);
return true;
}
return TileList::keyEvent(key);
}
void FileManager::TileDir::lock() {
if (screen && !resized) ((PIScreen*)screen)->lock();
}
void FileManager::TileDir::unlock() {
if (screen && !resized) ((PIScreen*)screen)->unlock();
}
void FileManager::TileDir::showReading() {
cur = -1;
offset = 0;
entries.clear();
content.resize(1);
content[0] = Row("... Reading ...", CellFormat());
}
void FileManager::TileDir::setContent(const PIVector<PIFile::FileInfo> & l) {
PIVector<PIFile::FileInfo> el = dir.entries(), fl, dl;
entries.clear();
if (l.isEmpty()) {
PIFile::FileInfo fi;
fi.path = "..";
fi.flags |= PIFile::FileInfo::DotDot | PIFile::FileInfo::Dir;
entries << fi;
} else {
bool root = dir.path() == PIDir::separator;
for (int i = 0; i < l.size_s(); ++i) {
if (l[i].name() == ".") continue;
if (l[i].name() == "..") {
if (!root) dl.push_front(l[i]);
continue;
}
if (l[i].isDir()) dl << l[i];
else fl << l[i];
}
entries << dl << fl;
}
}
void FileManager::TileDir::updateDir() {
//if (!enabled) return;
lock();
int pc = cur, po = offset;
showReading();
unlock();
setContent(dir.entries());
if (label_path) {
label_path->content.resize(1);
label_path->content[0].first = dir.absolutePath();
}
cur = pc;
offset = po;
buildNames();
}
void FileManager::TileDir::buildNames() {
//if (!enabled) return;
lock();
content.clear();
PIChar t;
CharFlags cf = 0;
Color cc = Default;
PIString fcol, scol;
piForeachC (PIFile::FileInfo & e, entries) {
if (e.isDir()) {
t = '/';
cf = Bold;
scol = " dir";
} else {
if (e.perm_user.exec || e.perm_group.exec || e.perm_other.exec) {
cf = Bold;
cc = Green;
t = '*';
} else {
t = ' ';
cf = 0;
}
scol = PIString::readableSize(e.size);
}
if (e.isSymbolicLink() && (t != '*')) t = '~';
scol = scol.expandRightTo(9, ' ') + "| " + e.time_modification.toString("dd.MM hh:mm:ss") + " | "
+ e.perm_user.toString() + " " + e.perm_group.toString() + " " + e.perm_other.toString();
fcol = t + e.name();
if (fcol.size_s() >= width - 2 - scol.size_s())
fcol = fcol.left(width - 5 - scol.size_s()) + "...";
fcol.expandRightTo(width - 1 - scol.size_s(), ' ');
content << Row(fcol + scol, CellFormat(cc, Transparent, cf));
}
unlock();
}
void FileManager::TileDir::sizeHint(int & w, int & h) const {
w = h = 4;
}
void FileManager::TileDir::resizeEvent(int w, int h) {
resized = true;
buildNames();
resized = false;
}
FileManager::FileManager(Daemon * d) {
setName("FileManager");
del_commit = false;
daemon = d;
CONNECTU(&screen, keyPressed, this, keyEvent)
//dir.setDir("/home/peri4/Documents");
TileSimple * tl;
tile_root = new PIScreenTile();
tile_root->direction = Vertical;
PIScreenTile * pt = new PIScreenTile();
pt->direction = Horizontal;
pt->spacing = 1;
pt->back_format.color_back = Cyan;
for (int i = 0; i < 2; ++i) {
PIScreenTile * panel = new PIScreenTile();
TileSimple * plabel = new TileSimple();
plabel->size_policy = Fixed;
plabel->maximumWidth = 1;
panel->direction = Vertical;
panels[i] = new TileDir();
panels[i]->fm = this;
panels[i]->key_func = (void*)tileKey_s;
panels[i]->setName("file panel " + PIString(i));
panels[i]->label_path = plabel;
panel->addTile(plabel);
panel->addTile(panels[i]);
panels[i]->updateDir();
pt->addTile(panel);
}
tile_root->addTile(pt);
PIScreenTile * labels = new PIScreenTile();
labels->size_policy = Fixed;
labels->direction = Horizontal;
PIVector<SSPair> ll;
ll << SSPair(" Esc", "Exit") << SSPair(" F5", "Copy") << SSPair(" F6", "Move") << SSPair(" F7", "MkDir") << SSPair(" F8", "Delete");
piForeachC (SSPair & l, ll) {
tl = new TileSimple(); labels->addTile(tl);
tl->content << TileSimple::Row(l.first, CellFormat(White, Transparent, Bold));
tl = new TileSimple(); labels->addTile(tl);
tl->content << TileSimple::Row(l.second, CellFormat(Black, Cyan));
}
tl = new TileSimple(); labels->addTile(tl);
tl->size_policy = Expanding;
tile_root->addTile(labels);
}
PIScreenTile * FileManager::tile() const {
return tile_root;
}
void FileManager::setRemoteDir(const PIString & d) {
panels[1]->dir.setDir(d);
if (panels[1]->label_path) {
panels[1]->label_path->content.resize(1);
panels[1]->label_path->content[0].first = panels[1]->dir.path();
}
}
void FileManager::setRemoteContent(const PIVector< PIFile::FileInfo > & el) {
panels[1]->setContent(el);
panels[1]->buildNames();
}
PIStringList FileManager::selectedRemote() const {
PIStringList ret;
panels[1]->lock();
PIVector<int> sil = panels[1]->selected.toVector();
piForeachC (int i, sil)
ret << panels[1]->entries[i].path;
panels[1]->unlock();
return ret;
}
PIFile::FileInfo FileManager::currentRemoteEntry() const {
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s())) return PIFile::FileInfo();
return panels[1]->entries[panels[1]->cur];
}
void FileManager::remoteSaveDir() {
panels[1]->prev_pos[panels[1]->dir.path()] = PIPair<int, int>(panels[1]->cur, panels[1]->offset);
}
void FileManager::remoteRestoreDir() {
PIPair<int, int> cp = panels[1]->prev_pos.value(panels[1]->dir.path());
panels[1]->selected.clear();
panels[1]->cur = cp.first;
panels[1]->offset = cp.second;
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s()))
panels[1]->cur = 0;
}
void FileManager::keyEvent(PIKbdListener::KeyEvent key) {
if (!tile_root->visible) return;
if (screen.dialogTile()) return;
switch (key.key) {
case PIKbdListener::Esc:
menuRequest();
break;
default: break;
}
/*if (!enabled) return;
if (key.key == 'D') {
if (cur >= files.size_s() || cur < 0) return;
if (del_commit) {
piForeachC (PIString & f, selected) {
PIFile::remove(dir.absolutePath() + PIDir::separator + f);
//piCout << "remove" << (dir.absolutePath() + PIDir::separator + f);
}
selected.clear();
updateDir();
console.clearCustomStatus();
del_commit = false;
} else {
if (selected.isEmpty()) selected << files[cur].path;
console.addCustomStatus("Delete " + PIString(selected.size_s()) + " file, are you sure? D as yes");
del_commit = true;
}
updateConsole();
return;
}
console.clearCustomStatus();
del_commit = false;
PIStringList nsel;
switch (key.key) {
case PIKbdListener::UpArrow:
cur--;
if (cur < 0) cur = 0;
if (cur - offset < 3) offset--;
if (offset < 0) offset = 0;
updateConsole();
break;
case PIKbdListener::Space:
if (cur < 0 || cur >= files.size_s()) return;
if (selected.contains(files[cur].path)) selected.removeOne(files[cur].path);
else selected << files[cur].path;
case PIKbdListener::DownArrow:
cur++;
if (cur >= files.size_s()) cur = files.size_s() - 1;
if (cur - offset >= height - 3) offset++;
if (offset >= files.size_s() - height) offset = files.size_s() - height;
updateConsole();
//piCout << offset << files.size_s() << height;
break;
case PIKbdListener::Home:
cur = offset = 0;
updateConsole();
break;
case PIKbdListener::End:
cur = files.size_s() - 1;
offset = files.size_s() - height;
updateConsole();
//piCout << offset << files.size_s() << height;
break;
case PIKbdListener::Return:
if (cur < files.size_s() && cur >= 0) {
piCout << files[cur];
if (files[cur].isDir()) {
prev_pos[dir.path()] = cur;
prev_off[dir.path()] = offset;
dir.cd(files[cur].name());
cur = prev_pos.value(dir.path(), 0);
offset = prev_off.value(dir.path(), 0);
selected.clear();
updateDir();
updateConsole();
}
}
break;
case 'A':
selected.clear();
piForeach (PIFile::FileInfo & e, files)
selected << e.path;
updateConsole();
break;
case 'R':
updateDir();
piForeach (PIFile::FileInfo & e, files)
if (selected.contains(e.path))
nsel << e.path;
selected = nsel;
updateConsole();
break;
case PIKbdListener::Esc:
//selected.clear();
//updateConsole();
menuRequest();
break;
default: break;
}*/
}
void FileManager::updateConsole() {
/*if (!enabled) return;
startTab(2);
console.addString("File manager", 1, Yellow | Inverse);
console.addString("Path: " + dir.absolutePath(), 1, Green | Inverse | Bold);
console.addString("Name", 1, Green | Inverse | Bold);
console.addString(" ", 2, Yellow | Inverse);
console.addString(" ", 2, Green | Inverse);
console.addString(" ", 2, Green | Inverse);
buildNames();
console.addString("A - select all, D - remove, R - refresh, Esc - exit", 1, Green | Inverse | Bold);
finishTab();*/
}