aboutsummaryrefslogtreecommitdiffstats
path: root/kde2/kpsion/kpsion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kde2/kpsion/kpsion.cpp')
-rw-r--r--kde2/kpsion/kpsion.cpp866
1 files changed, 726 insertions, 140 deletions
diff --git a/kde2/kpsion/kpsion.cpp b/kde2/kpsion/kpsion.cpp
index 808ed1a..2e605d9 100644
--- a/kde2/kpsion/kpsion.cpp
+++ b/kde2/kpsion/kpsion.cpp
@@ -41,16 +41,15 @@
#include <qtimer.h>
#include <qlayout.h>
#include <qiodevice.h>
+#include <qheader.h>
#include <qdir.h>
+#include <qmessagebox.h>
#include <ppsocket.h>
#include <rfsvfactory.h>
#include <rpcsfactory.h>
#include <bufferarray.h>
-#include <iomanip>
-#include <strstream>
-
// internal use for developing offline without
// having a Psion connected.
// !!!!! set to 0 for production code !!!!!
@@ -58,37 +57,88 @@
#define STID_CONNECTION 1
+class KPsionCheckListItem::KPsionCheckListItemMetaData {
+ friend KPsionCheckListItem;
+
+private:
+ KPsionCheckListItemMetaData();
+ ~KPsionCheckListItemMetaData() { };
+
+ bool parentIsKPsionCheckListItem;
+ bool dontPropagate;
+ int backupType;
+ int size;
+ time_t when;
+ u_int32_t timeHi;
+ u_int32_t timeLo;
+ u_int32_t attr;
+ QString name;
+};
+
+KPsionCheckListItem::KPsionCheckListItemMetaData::KPsionCheckListItemMetaData() {
+ when = 0;
+ size = 0;
+ timeHi = 0;
+ timeLo = 0;
+ attr = 0;
+ name = QString::null;
+ backupType = KPsionBackupListView::UNKNOWN;
+}
+
+KPsionCheckListItem::~KPsionCheckListItem() {
+ delete meta;
+}
+
+KPsionCheckListItem *KPsionCheckListItem::
+firstChild() const {
+ return (KPsionCheckListItem *)QListViewItem::firstChild();
+}
+
+KPsionCheckListItem *KPsionCheckListItem::
+nextSibling() const {
+ return (KPsionCheckListItem *)QListViewItem::nextSibling();
+}
+
void KPsionCheckListItem::
init(bool myparent) {
setSelectable(false);
- dontPropagate = false;
- parentIsKPsionCheckListItem = myparent;
+ meta = new KPsionCheckListItemMetaData();
+ meta->dontPropagate = false;
+ meta->parentIsKPsionCheckListItem = myparent;
}
void KPsionCheckListItem::
-setMetaData(int bType, time_t bWhen) {
- backupType = bType;
- when = bWhen;
+setMetaData(int type, time_t when, QString name, int size,
+ u_int32_t tHi, u_int32_t tLo, u_int32_t attr) {
+ meta->backupType = type;
+ meta->when = when;
+ meta->name = name;
+ meta->size = size;
+ meta->timeHi = tHi;
+ meta->timeLo = tLo;
+ meta->attr = attr;
}
void KPsionCheckListItem::
stateChange(bool state) {
QCheckListItem::stateChange(state);
- if (dontPropagate)
+ if (meta->dontPropagate)
return;
- if (parentIsKPsionCheckListItem)
- ((KPsionCheckListItem *)parent())->propagateUp(state);
+ if (meta->parentIsKPsionCheckListItem)
+ ((KPsionCheckListItem *)QListViewItem::parent())->propagateUp(state);
+ else
+ emit rootToggled();
propagateDown(state);
}
void KPsionCheckListItem::
propagateDown(bool state) {
setOn(state);
- KPsionCheckListItem *child = (KPsionCheckListItem *)firstChild();
+ KPsionCheckListItem *child = firstChild();
while (child) {
child->propagateDown(state);
- child = (KPsionCheckListItem *)child->nextSibling();
+ child = child->nextSibling();
}
}
@@ -96,15 +146,15 @@ void KPsionCheckListItem::
propagateUp(bool state) {
bool deactivateThis = false;
- KPsionCheckListItem *child = (KPsionCheckListItem *)firstChild();
+ KPsionCheckListItem *child = firstChild();
while (child) {
if ((child->isOn() != state) || (!child->isEnabled())) {
deactivateThis = true;
break;
}
- child = (KPsionCheckListItem *)child->nextSibling();
+ child = child->nextSibling();
}
- dontPropagate = true;
+ meta->dontPropagate = true;
if (deactivateThis) {
setOn(true);
setEnabled(false);
@@ -116,9 +166,68 @@ propagateUp(bool state) {
// enabled/disabled without activating.
// -> force it.
listView()->repaintItem(this);
- dontPropagate = false;
- if (parentIsKPsionCheckListItem)
- ((KPsionCheckListItem *)parent())->propagateUp(state);
+ meta->dontPropagate = false;
+ if (meta->parentIsKPsionCheckListItem)
+ ((KPsionCheckListItem *)QListViewItem::parent())->propagateUp(state);
+ else
+ emit rootToggled();
+}
+
+QString KPsionCheckListItem::
+key(int column, bool ascending) const {
+ if (meta->when) {
+ QString tmp;
+ tmp.sprintf("%08d", meta->when);
+ return tmp;
+ }
+ return text();
+}
+
+QString KPsionCheckListItem::
+psionname() {
+ if (meta->parentIsKPsionCheckListItem)
+ return meta->name;
+ else
+ return QString::null;
+}
+
+QString KPsionCheckListItem::
+unixname() {
+ if (meta->parentIsKPsionCheckListItem)
+ return KPsionMainWindow::psion2unix(meta->name);
+ else
+ return QString::null;
+}
+
+QString KPsionCheckListItem::
+tarname() {
+ if (meta->parentIsKPsionCheckListItem)
+ return ((KPsionCheckListItem *)QListViewItem::parent())->tarname();
+ else
+ return meta->name;
+}
+
+int KPsionCheckListItem::
+backupType() {
+ if (meta->parentIsKPsionCheckListItem)
+ return ((KPsionCheckListItem *)QListViewItem::parent())->backupType();
+ else
+ return meta->backupType;
+}
+
+time_t KPsionCheckListItem::
+when() {
+ if (meta->parentIsKPsionCheckListItem)
+ return ((KPsionCheckListItem *)QListViewItem::parent())->when();
+ else
+ return meta->when;
+}
+
+PlpDirent KPsionCheckListItem::
+plpdirent() {
+ assert(meta->parentIsKPsionCheckListItem);
+ return PlpDirent(meta->size, meta->attr, meta->timeHi, meta->timeLo,
+ meta->name);
}
KPsionBackupListView::KPsionBackupListView(QWidget *parent, const char *name)
@@ -133,17 +242,25 @@ KPsionBackupListView::KPsionBackupListView(QWidget *parent, const char *name)
setRootIsDecorated(true);
}
+KPsionCheckListItem *KPsionBackupListView::
+firstChild() const {
+ return (KPsionCheckListItem *)QListView::firstChild();
+}
+
void KPsionBackupListView::
readBackups(QString uid) {
QString bdir(backupDir);
bdir += "/";
bdir += uid;
QDir d(bdir);
+ kapp->processEvents();
const QFileInfoList *fil =
d.entryInfoList("*.tar.gz", QDir::Files|QDir::Readable, QDir::Name);
QFileInfoListIterator it(*fil);
QFileInfo *fi;
while ((fi = it.current())) {
+ kapp->processEvents();
+
bool isValid = false;
KTarGz tgz(fi->absFilePath());
const KTarEntry *te;
@@ -169,30 +286,51 @@ readBackups(QString uid) {
}
if (isValid) {
- QString n = i18n("%1 backup, created at %2").arg(bTypeName).arg(date.toString());
+ QString n = i18n("%1 backup, created at %2").arg(bTypeName).arg(KGlobal::locale()->formatDateTime(date, false));
+ QByteArray a = ((KTarFile *)te)->data();
+ QTextIStream indexData(a);
+
+ indexData.readLine();
+ indexData.flags(QTextStream::hex);
+ indexData.fill('0');
+ indexData.width(8);
KPsionCheckListItem *i =
new KPsionCheckListItem(this, n,
KPsionCheckListItem::CheckBox);
- i->setMetaData(bType, te->date());
- i->setPixmap(0, KGlobal::iconLoader()->loadIcon("mime_empty", KIcon::Small));
+ i->setMetaData(bType, te->date(), tgz.fileName(), 0, 0, 0, 0);
+ i->setPixmap(0, KGlobal::iconLoader()->loadIcon("mime_empty",
+ KIcon::Small));
+ connect(i, SIGNAL(rootToggled()), this, SLOT(slotRootToggled()));
+
QStringList files = tgz.directory()->entries();
for (QStringList::Iterator f = files.begin();
f != files.end(); f++)
if ((*f != "KPsionFullIndex") &&
(*f != "KPsionIncrementalIndex"))
- listTree(i, tgz.directory()->entry(*f), 0);
+ listTree(i, tgz.directory()->entry(*f), indexData, 0);
}
tgz.close();
++it;
}
+ header()->setClickEnabled(false);
+ header()->setResizeEnabled(false);
+ header()->setMovingEnabled(false);
+ setMinimumSize(columnWidth(0) + 4, height());
+ QWhatsThis::add(this, i18n(
+ "<qt>Here, you can select the available backups."
+ " Select the items you want to restore, the click"
+ " on <b>Start</b> to start restoring these items."
+ "</qt>"));
}
void KPsionBackupListView::
-listTree(KPsionCheckListItem *cli, const KTarEntry *te, int level) {
+listTree(KPsionCheckListItem *cli, const KTarEntry *te, QTextIStream &idx,
+ int level) {
KPsionCheckListItem *i =
new KPsionCheckListItem(cli, te->name(),
KPsionCheckListItem::CheckBox);
+ kapp->processEvents();
if (te->isDirectory()) {
if (level)
i->setPixmap(0, KGlobal::iconLoader()->loadIcon("folder",
@@ -200,17 +338,118 @@ listTree(KPsionCheckListItem *cli, const KTarEntry *te, int level) {
else
i->setPixmap(0, KGlobal::iconLoader()->loadIcon("hdd_unmount",
KIcon::Small));
+ i->setMetaData(0, 0, QString::null, 0, 0, 0, 0);
KTarDirectory *td = (KTarDirectory *)te;
QStringList files = td->entries();
for (QStringList::Iterator f = files.begin(); f != files.end(); f++)
- listTree(i, td->entry(*f), level + 1);
- } else
+ listTree(i, td->entry(*f), idx, level + 1);
+ } else {
+ uint32_t timeHi;
+ uint32_t timeLo;
+ uint32_t size;
+ uint32_t attr;
+ QString name;
+
i->setPixmap(0, KGlobal::iconLoader()->loadIcon("mime_empty",
KIcon::Small));
+ idx >> timeHi >> timeLo >> size >> attr >> name;
+ i->setMetaData(0, 0, name, size, timeHi, timeLo, attr);
+ }
+}
+
+void KPsionBackupListView::
+slotRootToggled() {
+ bool anyOn = false;
+ KPsionCheckListItem *i = firstChild();
+ while (i != 0L) {
+ if (i->isOn()) {
+ anyOn = true;
+ break;
+ }
+ i = i->nextSibling();
+ }
+ emit itemsEnabled(anyOn);
+}
+
+QStringList KPsionBackupListView::
+getSelectedTars() {
+ QStringList l;
+
+ KPsionCheckListItem *i = firstChild();
+ while (i != 0L) {
+ if (i->isOn())
+ l += i->tarname();
+ i = i->nextSibling();
+ }
+ return l;
+}
+
+bool KPsionBackupListView::
+autoSelect(QString drive) {
+ KPsionCheckListItem *latest = NULL;
+ time_t stamp = 0;
+
+ drive += ":";
+ // Find latest full backup for given drive
+ KPsionCheckListItem *i = firstChild();
+ while (i != 0L) {
+ if ((i->backupType() == FULL) && (i->when() > stamp)) {
+ KPsionCheckListItem *c = i->firstChild();
+ while (c != 0L) {
+ if (c->text() == drive) {
+ latest = c;
+ stamp = i->when();
+ break;
+ }
+ c = c->nextSibling();
+ }
+ }
+ i = i->nextSibling();
+ }
+ // Now find all incremental backups for given drive which are newer than
+ // selected backup
+ if (latest != 0) {
+ latest->setOn(true);
+ i = firstChild();
+ while (i != 0L) {
+ if ((i->backupType() == INCREMENTAL) && (i->when() >= stamp)) {
+ KPsionCheckListItem *c = i->firstChild();
+ while (c != 0L) {
+ if (c->text() == drive)
+ c->setOn(true);
+ c = c->nextSibling();
+ }
+ }
+ i = i->nextSibling();
+ }
+ }
+ return (latest != 0L);
+}
+
+void KPsionBackupListView::
+collectEntries(KPsionCheckListItem *i) {
+ while (i != 0L) {
+ KPsionCheckListItem *c = i->firstChild();
+ if (c == 0L) {
+ if (i->isOn())
+ toRestore.push_back(i->plpdirent());
+ } else
+ collectEntries(c);
+ i = i->nextSibling();
+ }
}
PlpDir &KPsionBackupListView::
-getRestoreList() {
+getRestoreList(QString tarname) {
+ toRestore.clear();
+ KPsionCheckListItem *i = firstChild();
+ while (i != 0L) {
+ if ((i->tarname() == tarname) && (i->isOn())) {
+ collectEntries(i->firstChild());
+ break;
+ }
+ i = i->nextSibling();
+ }
return toRestore;
}
@@ -222,6 +461,18 @@ KPsionMainWindow::KPsionMainWindow()
statusBar()->setItemAlignment(STID_CONNECTION,
QLabel::AlignLeft|QLabel::AlignVCenter);
+ progress = new KPsionStatusBarProgress(statusBar(), "progressBar");
+ statusBar()->addWidget(progress, 10);
+
+ connect(progress, SIGNAL(pressed()), this, SLOT(slotProgressBarPressed()));
+ connect(this, SIGNAL(setProgress(int)), progress, SLOT(setValue(int)));
+ connect(this, SIGNAL(setProgress(int, int)), progress,
+ SLOT(setValue(int, int)));
+ connect(this, SIGNAL(setProgressText(const QString &)), progress,
+ SLOT(setText(const QString &)));
+ connect(this, SIGNAL(enableProgressText(bool)), progress,
+ SLOT(setTextEnabled(bool)));
+
backupRunning = false;
restoreRunning = false;
formatRunning = false;
@@ -267,6 +518,11 @@ KPsionMainWindow::KPsionMainWindow()
connected = false;
shuttingDown = false;
+ args = KCmdLineArgs::parsedArgs();
+ if (args->isSet("autobackup")) {
+ firstTry = false;
+ reconnectTime = 0;
+ }
tryConnect();
}
@@ -282,6 +538,24 @@ KPsionMainWindow::~KPsionMainWindow() {
delete rpcsSocket;
}
+QString KPsionMainWindow::
+unix2psion(const char * const path) {
+ QString tmp = path;
+ tmp.replace(QRegExp("/"), "\\");
+ tmp.replace(QRegExp("%2f"), "/");
+ tmp.replace(QRegExp("%25"), "%");
+ return tmp;
+}
+
+QString KPsionMainWindow::
+psion2unix(const char * const path) {
+ QString tmp = path;
+ tmp.replace(QRegExp("%"), "%25");
+ tmp.replace(QRegExp("/"), "%2f");
+ tmp.replace(QRegExp("\\"), "/");
+ return tmp;
+}
+
void KPsionMainWindow::
setupActions() {
@@ -447,6 +721,18 @@ queryPsion() {
}
#endif
if (!machineFound) {
+ if (args->isSet("autobackup")) {
+ connected = false;
+ if (plpRfsv)
+ delete plpRfsv;
+ if (plpRpcs)
+ delete plpRpcs;
+ if (rfsvSocket)
+ delete rfsvSocket;
+ if (rfsvSocket)
+ delete rpcsSocket;
+ return;
+ }
NewPsionWizard *wiz = new NewPsionWizard(this, "newpsionwiz");
wiz->exec();
}
@@ -457,11 +743,9 @@ queryPsion() {
QString KPsionMainWindow::
getMachineUID() {
// ??! None of QString's formatting methods knows about long long.
- ostrstream s;
- s << hex << setw(16) << machineUID;
- QString ret = s.str();
- ret = ret.left(16);
- return ret;
+ char tmp[20];
+ sprintf(tmp, "%16llx", machineUID);
+ return QString(tmp);
}
bool KPsionMainWindow::
@@ -506,28 +790,37 @@ tryConnect() {
nextTry = reconnectTime;
statusMsg += i18n(" (Retry in %1 seconds.)");
QTimer::singleShot(1000, this, SLOT(slotUpdateTimer()));
+
+ statusBar()->changeItem(statusMsg.arg(reconnectTime),
+ STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg.arg(reconnectTime));
+ } else {
+ statusBar()->changeItem(statusMsg, STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg);
}
- statusBar()->changeItem(statusMsg.arg(reconnectTime),
- STID_CONNECTION);
- if (showMB)
- KMessageBox::error(this, statusMsg.arg(reconnectTime));
return;
}
rfsvfactory factory(rfsvSocket);
plpRfsv = factory.create(false);
if (plpRfsv == 0L) {
- statusMsg = i18n("RFSV could not establish link: %1.").arg(factory.getError());
+ statusMsg = i18n("RFSV could not establish link: %1.").arg(KGlobal::locale()->translate(factory.getError()));
delete rfsvSocket;
rfsvSocket = 0L;
if (reconnectTime) {
nextTry = reconnectTime;
statusMsg += i18n(" (Retry in %1 seconds.)");
QTimer::singleShot(1000, this, SLOT(slotUpdateTimer()));
+ statusBar()->changeItem(statusMsg.arg(reconnectTime),
+ STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg.arg(reconnectTime));
+ } else {
+ statusBar()->changeItem(statusMsg, STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg);
}
- statusBar()->changeItem(statusMsg.arg(reconnectTime),
- STID_CONNECTION);
- if (showMB)
- KMessageBox::error(this, statusMsg.arg(reconnectTime));
return;
}
@@ -542,17 +835,21 @@ tryConnect() {
nextTry = reconnectTime;
statusMsg += i18n(" (Retry in %1 seconds.)");
QTimer::singleShot(1000, this, SLOT(slotUpdateTimer()));
+ statusBar()->changeItem(statusMsg.arg(reconnectTime),
+ STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg.arg(reconnectTime));
+ } else {
+ statusBar()->changeItem(statusMsg, STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg);
}
- statusBar()->changeItem(statusMsg.arg(reconnectTime),
- STID_CONNECTION);
- if (showMB)
- KMessageBox::error(this, statusMsg.arg(reconnectTime));
return;
}
rpcsfactory factory2(rpcsSocket);
plpRpcs = factory2.create(false);
if (plpRpcs == 0L) {
- statusMsg = i18n("RPCS could not establish link: %1.").arg(factory.getError());
+ statusMsg = i18n("RPCS could not establish link: %1.").arg(KGlobal::locale()->translate(factory2.getError()));
delete plpRfsv;
plpRfsv = 0L;
delete rfsvSocket;
@@ -563,11 +860,15 @@ tryConnect() {
nextTry = reconnectTime;
statusMsg += i18n(" (Retry in %1 seconds.)");
QTimer::singleShot(1000, this, SLOT(slotUpdateTimer()));
+ statusBar()->changeItem(statusMsg.arg(reconnectTime),
+ STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg.arg(reconnectTime));
+ } else {
+ statusBar()->changeItem(statusMsg, STID_CONNECTION);
+ if (showMB)
+ KMessageBox::error(this, statusMsg);
}
- statusBar()->changeItem(statusMsg.arg(reconnectTime),
- STID_CONNECTION);
- if (showMB)
- KMessageBox::error(this, statusMsg.arg(reconnectTime));
return;
}
#endif
@@ -587,6 +888,10 @@ slotUpdateTimer() {
}
void KPsionMainWindow::
+slotProgressBarPressed() {
+}
+
+void KPsionMainWindow::
slotStartFullBackup() {
fullBackup = true;
doBackup();
@@ -598,33 +903,40 @@ slotStartIncBackup() {
doBackup();
}
+const KTarEntry *KPsionMainWindow::
+findTarEntry(const KTarEntry *te, QString path, QString rpath) {
+ const KTarEntry *fte = NULL;
+ if (te->isDirectory() && (path.left(rpath.length()) == rpath)) {
+ KTarDirectory *td = (KTarDirectory *)te;
+ QStringList files = td->entries();
+ for (QStringList::Iterator f = files.begin(); f != files.end(); f++) {
+ QString tmp = rpath;
+ if (tmp.length())
+ tmp += "/";
+ tmp += *f;
+ fte = findTarEntry(td->entry(*f), path, tmp);
+ if (fte != 0L)
+ break;
+ }
+ } else {
+ if (path == rpath)
+ fte = te;
+ }
+ return fte;
+}
+
void KPsionMainWindow::
doBackup() {
backupRunning = true;
switchActions();
toBackup.clear();
- KDialog *d = new KDialog(this, "backupDialog", false);
- d->setCaption(i18n("Backup"));
- QGridLayout *gl = new QGridLayout(d);
- progressLabel = new KSqueezedTextLabel(d);
- gl->addWidget(progressLabel, 1, 1);
- progress = new KProgress(0, 100, 0, KProgress::Horizontal, d,
- "backupProgress");
-
- gl->addWidget(progress, 2, 1);
- gl->addRowSpacing(0, KDialog::marginHint());
- gl->addRowSpacing(3, KDialog::marginHint());
- gl->addColSpacing(0, KDialog::marginHint());
- gl->addColSpacing(2, KDialog::marginHint());
- gl->setColStretch(1, 1);
- gl->setRowStretch(1, 1);
- d->setMinimumSize(250, 80);
- d->show();
// Collect list of files to backup
backupSize = 0;
backupCount = 0;
progressTotal = 0;
+ emit enableProgressText(true);
+ emit setProgress(0);
for (QIconViewItem *i = view->firstItem(); i; i = i->nextItem()) {
if (i->isSelected()) {
QString drv = i->key();
@@ -632,14 +944,16 @@ doBackup() {
int drvNum = *(drv.data()) - 'A';
PlpDrive drive;
if (plpRfsv->devinfo(drvNum, drive) != rfsv::E_PSI_GEN_NONE) {
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
+ emit enableProgressText(false);
+ emit setProgress(0);
KMessageBox::error(this, i18n("Could not retrieve drive details for drive %1").arg(drv));
- d->hide();
- delete d;
backupRunning = false;
switchActions();
return;
}
- progressLabel->setText(i18n("Scanning drive %1").arg(drv));
+ emit setProgressText(i18n("Scanning drive %1").arg(drv));
progressLocal = drive.getSize() - drive.getSpace();
progressLocalCount = 0;
@@ -648,17 +962,19 @@ doBackup() {
collectFiles(drv);
}
}
- progressLabel->setText(i18n("%1 files need backup").arg(backupSize));
+ emit setProgressText(i18n("%1 files need backup").arg(backupSize));
if (backupCount == 0) {
+ emit enableProgressText(false);
+ emit setProgress(0);
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
KMessageBox::information(this, i18n("No files need backup"));
- d->hide();
- delete d;
backupRunning = false;
switchActions();
return;
}
- statusBar()->message(i18n("Backup"));
+ // statusBar()->message(i18n("Backup"));
progressCount = 0;
progressTotal = backupSize;
progressPercent = -1;
@@ -671,10 +987,12 @@ doBackup() {
QDir archiveDir(archiveName);
if (!archiveDir.exists())
if (!archiveDir.mkdir(archiveName)) {
+ emit enableProgressText(false);
+ emit setProgress(0);
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
KMessageBox::error(this, i18n("Could not create backup folder %1").arg(archiveName));
- d->hide();
- delete d;
- statusBar()->clear();
+ // statusBar()->clear();
backupRunning = false;
switchActions();
return;
@@ -697,40 +1015,19 @@ doBackup() {
bool badBackup = false;
Enum<rfsv::errs> res;
// Now the real backup
+ progressTotalText = i18n("Backup %1% done");
for (int i = 0; i < toBackup.size(); i++) {
PlpDirent e = toBackup[i];
const char *fn = e.getName();
- const char *p;
- char *q;
- char unixname[1024];
-
- for (p = fn, q = unixname; *p; p++, q++)
- switch (*p) {
- case '%':
- *q++ = '%';
- *q++ = '2';
- *q = '5';
- break;
- case '/':
- *q++ = '%';
- *q++ = '2';
- *q= 'f';
- break;
- case '\\':
- *q = '/';
- break;
- default:
- *q = *p;
- }
- *q = '\0';
+ QString unixname = psion2unix(fn);
+ QByteArray ba;
+ QDataStream os(ba, IO_WriteOnly);
- ostrstream os;
-
- progressLabel->setText(i18n("Backing up %1").arg(fn));
+ emit setProgressText(QString("%1").arg(fn));
progressLocal = e.getSize();
progressLocalCount = 0;
progressLocalPercent = -1;
- progress->setValue(0);
+ emit setProgress(0);
u_int32_t handle;
@@ -751,10 +1048,9 @@ doBackup() {
do {
if ((res = plpRfsv->fread(handle, buff, RFSV_SENDLEN, len)) ==
rfsv::E_PSI_GEN_NONE) {
- os.write(buff, len);
+ os.writeRawBytes((char *)buff, len);
updateProgress(len);
}
- kapp->processEvents();
} while ((len > 0) && (res == rfsv::E_PSI_GEN_NONE));
delete[]buff;
plpRfsv->fclose(handle);
@@ -767,17 +1063,16 @@ doBackup() {
continue;
}
}
- backupTgz->writeFile(unixname, "root", "root", os.pcount(),
- os.str());
+ backupTgz->writeFile(unixname, "root", "root", ba.size(), ba.data());
}
if (!badBackup) {
// Reset archive attributes of all backuped files.
- progressLabel->setText(i18n("Resetting archive attributes ..."));
+ emit setProgressText(i18n("Resetting archive attributes"));
progressLocal = backupSize;
progressLocalCount = 0;
progressLocalPercent = -1;
- progress->setValue(0);
+ emit setProgress(0);
for (int i = 0; i < toBackup.size(); i++) {
PlpDirent e = toBackup[i];
const char *fn = e.getName();
@@ -802,41 +1097,327 @@ doBackup() {
delete backupTgz;
if (badBackup)
unlink(archiveName.data());
- d->hide();
- delete d;
backupRunning = false;
switchActions();
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
+ emit enableProgressText(false);
+ emit setProgress(0);
statusBar()->message(i18n("Backup done"), 2000);
}
+KPsionRestoreDialog::KPsionRestoreDialog(QWidget *parent, QString uid)
+ : KDialogBase(parent, "restoreDialog", true, i18n("Restore"),
+ KDialogBase::Cancel | KDialogBase::Ok,
+ KDialogBase::Ok, true) {
+
+ setButtonOKText(i18n("Start"));
+ enableButtonOK(false);
+ setButtonWhatsThis(KDialogBase::Ok,
+ i18n("Select items in the list of"
+ " available backups, then click"
+ " here to start restore of these"
+ " items."));
+
+ QWidget *w = new QWidget(this);
+ setMainWidget(w);
+ QGridLayout *gl = new QGridLayout(w, 1, 1, KDialog::marginHint(),
+ KDialog::marginHint());
+ backupView = new KPsionBackupListView(w, "restoreSelector");
+ gl->addWidget(backupView, 0, 0);
+ backupView->readBackups(uid);
+ connect(backupView, SIGNAL(itemsEnabled(bool)), this,
+ SLOT(slotBackupsSelected(bool)));
+}
+
+void KPsionRestoreDialog::
+slotBackupsSelected(bool any) {
+ enableButtonOK(any);
+}
+
+QStringList KPsionRestoreDialog::
+getSelectedTars() {
+ return backupView->getSelectedTars();
+}
+
+bool KPsionRestoreDialog::
+autoSelect(QString drive) {
+ return backupView->autoSelect(drive);
+}
+
+PlpDir &KPsionRestoreDialog::
+getRestoreList(QString tarname) {
+ return backupView->getRestoreList(tarname);
+}
+
+bool KPsionMainWindow::
+askOverwrite(PlpDirent e) {
+ if (overWriteAll)
+ return true;
+ const char *fn = e.getName();
+ if (overWriteList.contains(QString(fn)))
+ return true;
+ PlpDirent old;
+ Enum<rfsv::errs> res = plpRfsv->fgeteattr(fn, old);
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not get attributes of<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(fn).arg(KGlobal::locale()->translate(res)));
+ return false;
+ }
+
+ // Don't ask if size and attribs are same
+ if ((old.getSize() == e.getSize()) &&
+ ((old.getAttr() & ~rfsv::PSI_A_ARCHIVE) ==
+ (e.getAttr() & ~rfsv::PSI_A_ARCHIVE)))
+ return true;
+
+ QDateTime odate;
+ QDateTime ndate;
+
+ odate.setTime_t(old.getPsiTime().getTime());
+ ndate.setTime_t(e.getPsiTime().getTime());
+
+ // Dates
+ QString od = KGlobal::locale()->formatDateTime(odate, false);
+ QString nd = KGlobal::locale()->formatDateTime(ndate, false);
+
+ // Sizes
+ QString os = QString("%1 (%2)").arg(KIO::convertSize(old.getSize())).arg(KGlobal::locale()->formatNumber(old.getSize(), 0));
+ QString ns = QString("%1 (%2)").arg(KIO::convertSize(e.getSize())).arg(KGlobal::locale()->formatNumber(e.getSize(), 0));
+
+ // Attributes
+ QString oa(plpRfsv->attr2String(old.getAttr()).c_str());
+ QString na(plpRfsv->attr2String(e.getAttr()).c_str());
+
+ KDialogBase dialog(i18n("Overwrite"), KDialogBase::Yes | KDialogBase::No |
+ KDialogBase::Cancel, KDialogBase::No,
+ KDialogBase::Cancel, this, "overwriteDialog", true, true,
+ QString::null, QString::null, i18n("Overwrite &All"));
+
+ QWidget *contents = new QWidget(&dialog);
+ QHBoxLayout * lay = new QHBoxLayout(contents);
+ lay->setSpacing(KDialog::spacingHint()*2);
+ lay->setMargin(KDialog::marginHint()*2);
+
+ lay->addStretch(1);
+ QLabel *label1 = new QLabel(contents);
+ label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Warning,
+ kapp->style().guiStyle()));
+ lay->add(label1);
+ lay->add(new QLabel(i18n(
+ "<QT>The file <B>%1</B> exists already on the Psion with "
+ "different size and/or attributes."
+ "<P><B>On the Psion:</B><BR/>"
+ " Size: %2<BR/>"
+ " Date: %3<BR/>"
+ " Attributes: %4</P>"
+ "<P><B>In backup:</B><BR/>"
+ " Size: %5<BR/>"
+ " Date: %6<BR/>"
+ " Attributes: %7</P>"
+ "Do you want to overwrite it?</QT>").arg(fn).arg(os).arg(od).arg(oa).arg(ns).arg(nd).arg(na), contents));
+ lay->addStretch(1);
+
+ dialog.setMainWidget(contents);
+ dialog.enableButtonSeparator(false);
+
+ int result = dialog.exec();
+ switch (result) {
+ case KDialogBase::Yes:
+ return true;
+ case KDialogBase::No:
+ return false;
+ case KDialogBase::Cancel:
+ overWriteAll = true;
+ return true;
+ default: // Huh?
+ break;
+ }
+
+ return false; // Default
+}
+
void KPsionMainWindow::
slotStartRestore() {
restoreRunning = true;
switchActions();
- KDialog *d = new KDialog(this, "restoreDialog", true);
- d->setCaption(i18n("Restore"));
- QGridLayout *gl = new QGridLayout(d);
- //progressLabel = new KSqueezedTextLabel(d);
- KPsionBackupListView *v = new KPsionBackupListView(d, "restoreSelector");
- gl->addWidget(v, 1, 1);
- //progress = new KProgress(0, 100, 0, KProgress::Horizontal, d, "restoreProgress");
-
- //gl->addWidget(progress, 2, 1);
- gl->addRowSpacing(0, KDialog::marginHint());
- gl->addRowSpacing(3, KDialog::marginHint());
- gl->addColSpacing(0, KDialog::marginHint());
- gl->addColSpacing(2, KDialog::marginHint());
- gl->setColStretch(1, 1);
- gl->setRowStretch(1, 1);
- d->setMinimumSize(250, 80);
- v->readBackups(getMachineUID());
- d->exec();
-
- d->hide();
- delete d;
+ kapp->setOverrideCursor(Qt::waitCursor);
+ statusBar()->changeItem(i18n("Reading backups ..."), STID_CONNECTION);
+ update();
+ kapp->processEvents();
+ KPsionRestoreDialog restoreDialog(this, getMachineUID());
+ kapp->restoreOverrideCursor();
+ statusBar()->changeItem(i18n("Selecting backups ..."), STID_CONNECTION);
+
+ for (QIconViewItem *i = view->firstItem(); i; i = i->nextItem()) {
+ if (i->isSelected() && (i->key() != "Z"))
+ restoreDialog.autoSelect(i->key());
+ }
+
+ overWriteList.clear();
+ overWriteAll = false;
+
+ if (restoreDialog.exec() == KDialogBase::Accepted) {
+ QStringList tars = restoreDialog.getSelectedTars();
+ QStringList::Iterator t;
+
+ backupSize = 0;
+ backupCount = 0;
+ for (t = tars.begin(); t != tars.end(); t++) {
+ PlpDir toRestore = restoreDialog.getRestoreList(*t);
+ for (int r = 0; r < toRestore.size(); r++) {
+ PlpDirent e = toRestore[r];
+ backupSize += e.getSize();
+ backupCount++;
+ }
+ }
+ if (backupCount == 0) {
+ restoreRunning = false;
+ switchActions();
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
+ return;
+ }
+
+ progressTotalText = i18n("Restore %1% done");
+ progressTotal = backupSize;
+ progressCount = 0;
+ progressPercent = -1;
+ emit setProgressText("");
+ emit enableProgressText(true);
+ emit setProgress(0);
+
+ // Kill all running applications on the Psion
+ // and save their state.
+ killSave();
+
+ for (t = tars.begin(); t != tars.end(); t++) {
+ PlpDir toRestore = restoreDialog.getRestoreList(*t);
+ if (toRestore.size() > 0) {
+ KTarGz tgz(*t);
+ const KTarEntry *te;
+ QString pDir("");
+
+ tgz.open(IO_ReadOnly);
+ for (int r = 0; r < toRestore.size(); r++) {
+ PlpDirent e = toRestore[r];
+ PlpDirent olde;
+
+ const char *fn = e.getName();
+ QString unixname = psion2unix(fn);
+ Enum<rfsv::errs> res;
+
+ progressLocal = e.getSize();
+ progressLocalCount = 0;
+ progressLocalPercent = -1;
+ emit setProgressText(QString("%1").arg(fn));
+ emit setProgress(0);
+
+ te = findTarEntry(tgz.directory(), unixname);
+ if (te != 0L) {
+ u_int32_t handle;
+ QString cpDir(fn);
+ QByteArray ba = ((KTarFile *)te)->data();
+ int bslash = cpDir.findRev('\\');
+ if (bslash > 0)
+ cpDir = cpDir.left(bslash);
+ if (pDir != cpDir) {
+ pDir = cpDir;
+ res = plpRfsv->mkdir(pDir);
+ if ((res != rfsv::E_PSI_GEN_NONE) &&
+ (res != rfsv::E_PSI_FILE_EXIST)) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not create directory<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(pDir).arg(KGlobal::locale()->translate(res)));
+ continue;
+ }
+ }
+ res = plpRfsv->fcreatefile(
+ plpRfsv->opMode(rfsv::PSI_O_RDWR), fn, handle);
+ if (res == rfsv::E_PSI_FILE_EXIST) {
+ if (!askOverwrite(e))
+ continue;
+ res = plpRfsv->freplacefile(
+ plpRfsv->opMode(rfsv::PSI_O_RDWR), fn, handle);
+ }
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not create<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(fn).arg(KGlobal::locale()->translate(res)));
+ continue;
+ }
+ const unsigned char *data =
+ (const unsigned char *)(ba.data());
+ long len = ba.size();
+
+ do {
+ u_int32_t written;
+ u_int32_t count =
+ (len > RFSV_SENDLEN) ? RFSV_SENDLEN : len;
+ res = plpRfsv->fwrite(handle, data, count, written);
+ if (res != rfsv::E_PSI_GEN_NONE)
+ break;
+ len -= written;
+ data += written;
+ updateProgress(written);
+ } while (len > 0);
+ plpRfsv->fclose(handle);
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not write to<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(fn).arg(KGlobal::locale()->translate(res)));
+ continue;
+ }
+ u_int32_t oldattr;
+ res = plpRfsv->fgetattr(fn, oldattr);
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not get attributes of<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(fn).arg(KGlobal::locale()->translate(res)));
+ continue;
+ }
+ u_int32_t mask = e.getAttr() ^ oldattr;
+ u_int32_t sattr = e.getAttr() & mask;
+ u_int32_t dattr = ~sattr & mask;
+ res = plpRfsv->fsetattr(fn, sattr, dattr);
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not set attributes of<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(fn).arg(KGlobal::locale()->translate(res)));
+ continue;
+ }
+ res = plpRfsv->fsetmtime(fn, e.getPsiTime());
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ KMessageBox::error(this, i18n(
+ "<QT>Could not set modification time of<BR/>"
+ "<B>%1</B><BR/>Reason: %2</QT>").arg(fn).arg(KGlobal::locale()->translate(res)));
+ continue;
+ }
+ overWriteList += QString(fn);
+ }
+ }
+ tgz.close();
+ }
+ }
+ // Restart previously running applications on the Psion
+ // from saved state info.
+ runRestore();
+ } else {
+ restoreRunning = false;
+ switchActions();
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
+ return;
+ }
+
restoreRunning = false;
switchActions();
+ emit setProgress(0);
+ emit enableProgressText(false);
+ statusBar()->changeItem(i18n("Connected to %1").arg(machineName),
+ STID_CONNECTION);
statusBar()->message(i18n("Restore done"), 2000);
}
@@ -885,7 +1466,7 @@ updateProgress(unsigned long amount) {
else
progressLocalPercent = 100;
if (progressLocalPercent != lastPercent)
- progress->setValue(progressLocalPercent);
+ emit setProgress(progressLocalPercent);
if (progressTotal > 0) {
progressCount += amount;
lastPercent = progressPercent;
@@ -894,8 +1475,10 @@ updateProgress(unsigned long amount) {
else
progressPercent = 100;
if (progressPercent != lastPercent)
- statusBar()->message(i18n("Backup %1% complete").arg(progressPercent));
+ statusBar()->changeItem(progressTotalText.arg(progressPercent),
+ STID_CONNECTION);
}
+ kapp->processEvents();
}
void KPsionMainWindow::
@@ -920,7 +1503,6 @@ collectFiles(QString dir) {
if (attr & rfsv::PSI_A_DIR) {
collectFiles(tmp);
} else {
- kapp->processEvents();
updateProgress(e.getSize());
if ((attr & rfsv::PSI_A_ARCHIVE) || fullBackup) {
backupCount++;
@@ -959,7 +1541,7 @@ killSave() {
cmdline += bs.getString(0);
savedCommands += cmdline;
}
- progressLabel->setText(i18n("Stopping %1").arg(cmdargs.getString(0)));
+ emit setProgressText(i18n("Stopping %1").arg(cmdargs.getString(0)));
kapp->processEvents();
plpRpcs->stopProgram(pbuf);
}
@@ -981,7 +1563,7 @@ runRestore() {
// These do not storethe full program path.
// In that case we try running the arg1 which
// results in starting the program via recog. facility.
- progressLabel->setText(i18n("Starting %1").arg(cmd));
+ emit setProgressText(i18n("Starting %1").arg(cmd));
kapp->processEvents();
if ((arg.length() > 2) && (arg[1] == ':') && (arg[0] >= 'A') &&
(arg[0] <= 'Z'))
@@ -1016,7 +1598,8 @@ runRestore() {
void KPsionMainWindow::
createIndex() {
- ostrstream os;
+ QByteArray ba;
+ QTextOStream os(ba);
os << "#plpbackup index " <<
(fullBackup ? "F" : "I") << endl;
for (int i = 0; i < toBackup.size(); i++) {
@@ -1036,7 +1619,10 @@ createIndex() {
<< setw(0) << e.getName() << endl;
kapp->processEvents();
}
- backupTgz->writeFile("Index", "root", "root", os.pcount(), os.str());
+ QString idxName =
+ QString::fromLatin1("KPsion%1Index").arg(fullBackup ?
+ "Full" : "Incremental");
+ backupTgz->writeFile(idxName, "root", "root", ba.size(), ba.data());
}
/*