PIString fix

git-svn-id: svn://db.shs.com.ru/pip@44 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
2015-03-30 08:49:19 +00:00
parent 8c051235aa
commit 595543bea9
8 changed files with 301 additions and 69 deletions

View File

@@ -10,6 +10,7 @@ Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + P
mode = offset = cur = height = 0;
CONNECTU(&screen, keyPressed, this, keyEvent)
CONNECTU(&timer, tickEvent, this, timerEvent)
CONNECTU(&fm, tileKey, this, fmKeyEvent)
timer.addDelimiter(5);
timer.start(200);
@@ -35,6 +36,7 @@ Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + P
tile_info = new TileSimple("daemon info");
tile_info->hide();
fm.setRemote(true);
tile_fm = fm.tile();
tile_fm->hide();
@@ -49,6 +51,14 @@ Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + P
}
Daemon::~Daemon() {
PIVector<Remote*> rl = remotes.values();
piForeach (Remote * r, rl)
delete r;
remotes.clear();
}
PIScreenTile * Daemon::tile() const {
return tile_root;
}
@@ -110,7 +120,11 @@ void Daemon::tileEvent(PIScreenTile * t, TileEvent e) {
if (e.type == TileList::RowPressed) {
switch (e.data.toInt()) {
case 0: mode = 2; showTile(tile_info, "Information"); break;
case 1: mode = 3; showTile(tile_fm, "File manager"); break;
case 1:
mode = 3;
showTile(tile_fm, "File manager");
requestChDir(".");
break;
default: break;
}
}
@@ -141,6 +155,26 @@ void Daemon::keyEvent(PIKbdListener::KeyEvent key) {
}
void Daemon::fmKeyEvent(PIKbdListener::KeyEvent key) {
PIByteArray ba;
//Remote * r = remotes.value(conn_name);
//piCout << key.key << key.modifiers;
switch (key.key) {
case PIKbdListener::Return:
{
PIFile::FileInfo fi = fm.currentRemoteEntry();
if (!fi.isDir()) break;
requestChDir(fi.name());
}
break;
case 'R':
requestChDir(".");
break;
default: break;
}
}
void Daemon::timerEvent(void * _d, int delim) {
screen.lock();
list_daemons->content.clear();
@@ -192,6 +226,10 @@ void Daemon::peerConnected(const PIString & name) {
/*piCout << "connected" << name;
mode = 2;
conn_name = name;*/
Remote * r = new Remote(name);
CONNECTU(&(r->dt), sendRequest, this, dtSendRequest)
CONNECTU(&(r->dt), receiveFinished, this, dtReceived)
remotes.insert(name, r);
}
@@ -199,6 +237,26 @@ void Daemon::peerDisconnected(const PIString & name) {
if (name == conn_name) {
disconnect();
}
Remote * dt = remotes.value(name);
if (dt) delete dt;
remotes.remove(name);
}
void Daemon::dtSendRequest(PIByteArray & data) {
PIDataTransfer * dt = (PIDataTransfer*)emitter();
if (!dt) return;
PIByteArray hdr; hdr << int(DataTransfer);
data.insert(0, hdr);
send(dt->name(), data);
}
void Daemon::dtReceived(bool ok) {
if (!ok) return;
PIDataTransfer * dt = (PIDataTransfer*)emitter();
if (!dt) return;
dataReceived(emitter()->name(), dt->data());
}
@@ -206,6 +264,8 @@ void Daemon::dataReceived(const PIString & from, const PIByteArray & data) {
//if (conn_name != from) return;
if (data.size() < 4) return;
PIByteArray ba(data), rba;
Remote * r(0);
PIString dir;
int type; ba >> type;
//std::cout << "rec from " << from << type;
switch (type) {
@@ -213,11 +273,40 @@ void Daemon::dataReceived(const PIString & from, const PIByteArray & data) {
makeMyHostInfo();
rba << int(ReplyHostInfo) << info_my;
break;
case RequestChangeDir:
r = remotes.value(from);
if (!r) break;
ba >> dir;
r->dir.cd(dir);
{
PIVector<PIFile::FileInfo> fil = r->dir.entries();
piForeach (PIFile::FileInfo & f, fil)
f.path = f.name();
rba << int(ReplyChangeDir) << r->dir.absolutePath() << fil;
}
break;
case ReplyHostInfo:
ba >> info_other;
makeOtherHostInfo();
fillInfoTile(info_other);
break;
case ReplyChangeDir:
r = remotes.value(from);
if (!r) break;
{
PIVector<PIFile::FileInfo> fil;
ba >> dir >> fil;
r->dir.setDir(dir);
fm.setRemoteDir(dir);
fm.setRemoteContent(fil);
fm.remoteRestoreDir();
}
break;
case DataTransfer:
r = remotes.value(from);
if (r)
r->dt.received(ba);
break;
};
if (!rba.isEmpty()) send(from, rba);
}
@@ -310,3 +399,14 @@ void Daemon::tabInfo() {
console.addVariable("of this process", &sys_mon_other, 2);
finishTab();*/
}
void Daemon::requestChDir(const PIString & d) {
if (d.isEmpty()) return;
fm.remoteSaveDir();
fm.readingRemote();
PIByteArray ba;
ba << int(RequestChangeDir) << d;
send(conn_name, ba);
//piCout << "request chdir" << d;
}

View File

@@ -4,6 +4,8 @@
#include "piscreentiles.h"
#include "pipeer.h"
#include "pisystemmonitor.h"
#include "pidatatransfer.h"
#include "pifiletransfer.h"
#include "file_manager.h"
extern PISystemMonitor sys_mon;
@@ -12,6 +14,7 @@ class Daemon: public PIPeer {
PIOBJECT(Daemon)
public:
Daemon();
~Daemon();
struct HostInfo {
HostInfo() {
@@ -52,14 +55,32 @@ public:
private:
enum PacketType {
RequestHostInfo = 10,
RequestChangeDir,
ReplyHostInfo = 20
ReplyHostInfo = 20,
ReplyChangeDir,
DataTransfer = 30
};
class Remote: public PIThread {
public:
Remote(const PIString & n = PIString()) {dt.setName(n); ft.setName(n); dir = PIDir::current();}
void sendData(const PIByteArray & d) {_d = d; startOnce();}
PIDir dir;
PIDataTransfer dt;
PIFileTransfer ft;
PIByteArray _d;
void run() {dt.send(_d);}
};
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e);
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER1(void, fmKeyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER2(void, timerEvent, void * , _d, int, delim);
EVENT_HANDLER1(void, dtSendRequest, PIByteArray &, data);
EVENT_HANDLER1(void, dtReceived, bool, ok);
EVENT(menuRequest);
void hideAll();
void showTile(PIScreenTile * t, const PIString & header = PIString());
@@ -75,10 +96,13 @@ private:
void tabFeature();
void tabInfo();
void requestChDir(const PIString & d);
mutable PIStringList available_daemons;
PITimer timer;
PIString conn_name;
PIMap<int, PIString> dnames;
PIMap<PIString, Remote*> remotes;
PISystemMonitor sys_mon_other;
HostInfo info_my, info_other;
FileManager fm;

View File

@@ -8,22 +8,34 @@ FileManager::TileDir::TileDir(): TileList() {
label_path = 0;
selection_mode = TileList::MultiSelection;
dir = PIDir::current();
resized = false;
resized = remote = false;
}
bool FileManager::TileDir::keyEvent(PIKbdListener::KeyEvent key) {
if (key.key == 'R') {
if (remote) {
((void(*)(void*,PIKbdListener::KeyEvent))key_func)(fm, key);
} else {
updateDir();
}
return true;
}
if (key.key == PIKbdListener::Return) {
if (cur < entries.size_s() && cur >= 0) {
//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();
if (remote) {
((void(*)(void*,PIKbdListener::KeyEvent))key_func)(fm, key);
} else {
//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();
}
}
}
return true;
@@ -42,34 +54,45 @@ void FileManager::TileDir::unlock() {
}
void FileManager::TileDir::updateDir() {
//if (!enabled) return;
entries.clear();
lock();
int pc = cur, po = offset;
void FileManager::TileDir::showReading() {
cur = -1;
offset = 0;
entries.clear();
content.resize(1);
content[0] = Row("... Reading ...", CellFormat());
unlock();
}
void FileManager::TileDir::setContent(const PIVector<PIFile::FileInfo> & l) {
PIVector<PIFile::FileInfo> el = dir.entries(), fl, dl;
if (el.isEmpty()) {
entries.clear();
if (l.isEmpty()) {
PIFile::FileInfo fi;
fi.path = "..";
fi.flags |= PIFile::FileInfo::DotDot | PIFile::FileInfo::Dir;
entries << fi;
} else {
for (int i = 0; i < el.size_s(); ++i) {
if (el[i].name() == ".") continue;
if (el[i].name() == "..") {
dl.push_front(el[i]);
for (int i = 0; i < l.size_s(); ++i) {
if (l[i].name() == ".") continue;
if (l[i].name() == "..") {
dl.push_front(l[i]);
continue;
}
if (el[i].isDir()) dl << el[i];
else fl << el[i];
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();
@@ -152,6 +175,8 @@ FileManager::FileManager(Daemon * d) {
plabel->maximumWidth = 1;
panel->direction = Vertical;
panels[i] = new TileDir();
panels[i]->fm = this;
panels[i]->key_func = (void*)tileKey_s;
panels[i]->name = "file panel " + PIString(i);
panels[i]->label_path = plabel;
panel->addTile(plabel);
@@ -184,6 +209,53 @@ PIScreenTile * FileManager::tile() const {
}
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.absolutePath();
}
}
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;
switch (key.key) {

View File

@@ -12,6 +12,18 @@ public:
FileManager(Daemon * d = 0);
PIScreenTile * tile() const;
PIScreenTile * remoteTile() const {return panels[1];}
void setRemote(bool r) {panels[1]->remote = r;}
void setRemoteDir(const PIString & d);
void setRemoteContent(const PIVector<PIFile::FileInfo> & el);
PIString remoteDir() const {return panels[1]->dir.absolutePath();}
PIStringList selectedRemote() const;
PIFile::FileInfo currentRemoteEntry() const;
PIFile::FileInfo selectedRemoteEntry(int index) const {return panels[1]->entries[index];}
void remoteSaveDir();
void remoteRestoreDir();
void readingRemote() const {panels[1]->showReading();}
private:
class TileDir: public TileList {
@@ -24,15 +36,20 @@ private:
void resizeEvent(int w, int h);
void lock();
void unlock();
void showReading();
void setContent(const PIVector<PIFile::FileInfo> & l);
TileSimple * label_path;
PIVector<PIFile::FileInfo> entries;
PIDir dir;
PIMap<PIString, PIPair<int, int> > prev_pos;
bool resized;
bool resized, remote;
void * fm, * key_func;
};
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, key);
EVENT1(tileKey, PIKbdListener::KeyEvent, key);
EVENT(menuRequest);
static void tileKey_s(void * fm, PIKbdListener::KeyEvent key) {((FileManager*)fm)->tileKey(key);}
void updateConsole();
bool del_commit;