PIString fix
git-svn-id: svn://db.shs.com.ru/pip@44 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user