* Applied patch by sil2100 that basically adds a "Yes to all" button, see
ticket #4059. I fixed a few style violations, though. Thanks! * Automatic whitespace cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32161 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2009, Haiku, Inc.
|
* Copyright 2007-2009, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Author:
|
* Author:
|
||||||
@@ -9,16 +9,19 @@
|
|||||||
|
|
||||||
#include "PackageItem.h"
|
#include "PackageItem.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
|
#include <fs_info.h>
|
||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
#include <SymLink.h>
|
#include <SymLink.h>
|
||||||
#include <Volume.h>
|
#include <Volume.h>
|
||||||
|
|
||||||
#include <fs_info.h>
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
|
|
||||||
// Macro reserved for later localization
|
// Macro reserved for later localization
|
||||||
#define T(x) x
|
#define T(x) x
|
||||||
|
|
||||||
@@ -160,25 +163,6 @@ PackageItem::SetTo(BFile *parent, const BString &path, uint8 type, uint32 ctime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
|
||||||
PackageItem::ItemExists(const char *name)
|
|
||||||
{
|
|
||||||
// TODO: this function doesn't really fit in, the GUI should be separated
|
|
||||||
// from the package engine completely
|
|
||||||
|
|
||||||
BString alertString = "The ";
|
|
||||||
|
|
||||||
alertString << ItemKind() << " named \'" << name << "\' ";
|
|
||||||
alertString << T("already exists in the given path. Should I replace "
|
|
||||||
"the existing file with the one from this package?");
|
|
||||||
|
|
||||||
BAlert *alert = new BAlert(T("file_exists"), alertString.String(),
|
|
||||||
T("Yes"), T("No"), T("Abort"));
|
|
||||||
|
|
||||||
return alert->Go();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageItem::InitPath(const char *path, BPath *destination)
|
PackageItem::InitPath(const char *path, BPath *destination)
|
||||||
{
|
{
|
||||||
@@ -446,25 +430,28 @@ PackageItem::ParseData(uint8 *buffer, BFile *file, uint64 originalSize,
|
|||||||
|
|
||||||
PackageDirectory::PackageDirectory(BFile *parent, const BString &path,
|
PackageDirectory::PackageDirectory(BFile *parent, const BString &path,
|
||||||
uint8 type, uint32 ctime, uint32 mtime, uint64 offset, uint64 size)
|
uint8 type, uint32 ctime, uint32 mtime, uint64 offset, uint64 size)
|
||||||
: PackageItem(parent, path, type, ctime, mtime, offset, size)
|
:
|
||||||
|
PackageItem(parent, path, type, ctime, mtime, offset, size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageDirectory::WriteToPath(const char *path, BPath *final)
|
PackageDirectory::WriteToPath(const char *path, ItemState *state)
|
||||||
{
|
{
|
||||||
BPath destination;
|
BPath &destination = state->destination;
|
||||||
status_t ret;
|
status_t ret;
|
||||||
parser_debug("Directory: %s WriteToPath() called!\n", fPath.String());
|
parser_debug("Directory: %s WriteToPath() called!\n", fPath.String());
|
||||||
|
|
||||||
ret = InitPath(path, &destination);
|
ret = InitPath(path, &destination);
|
||||||
|
parser_debug("Ret: %d %s\n", ret, strerror(ret));
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// Since Haiku is single-user right now, we give the newly
|
// Since Haiku is single-user right now, we give the newly
|
||||||
// created directory default permissions
|
// created directory default permissions
|
||||||
ret = create_directory(destination.Path(), kDefaultMode);
|
ret = create_directory(destination.Path(), kDefaultMode);
|
||||||
|
parser_debug("Create dir ret: %d %s\n", ret, strerror(ret));
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
BDirectory dir(destination.Path());
|
BDirectory dir(destination.Path());
|
||||||
@@ -481,9 +468,7 @@ PackageDirectory::WriteToPath(const char *path, BPath *final)
|
|||||||
if (fOffset)
|
if (fOffset)
|
||||||
ret = HandleAttributes(&destination, &dir, "FoDa");
|
ret = HandleAttributes(&destination, &dir, "FoDa");
|
||||||
|
|
||||||
if (final)
|
parser_debug("Ret: %d %s\n", ret, strerror(ret));
|
||||||
*final = destination;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,7 +487,8 @@ PackageFile::PackageFile(BFile *parent, const BString &path, uint8 type,
|
|||||||
uint32 ctime, uint32 mtime, uint64 offset, uint64 size,
|
uint32 ctime, uint32 mtime, uint64 offset, uint64 size,
|
||||||
uint64 originalSize, uint32 platform, const BString &mime,
|
uint64 originalSize, uint32 platform, const BString &mime,
|
||||||
const BString &signature, uint32 mode)
|
const BString &signature, uint32 mode)
|
||||||
: PackageItem(parent, path, type, ctime, mtime, offset, size),
|
:
|
||||||
|
PackageItem(parent, path, type, ctime, mtime, offset, size),
|
||||||
fOriginalSize(originalSize),
|
fOriginalSize(originalSize),
|
||||||
fPlatform(platform),
|
fPlatform(platform),
|
||||||
fMode(mode),
|
fMode(mode),
|
||||||
@@ -513,43 +499,55 @@ PackageFile::PackageFile(BFile *parent, const BString &path, uint8 type,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageFile::WriteToPath(const char *path, BPath *final)
|
PackageFile::WriteToPath(const char *path, ItemState *state)
|
||||||
{
|
{
|
||||||
BPath destination;
|
if (state == NULL)
|
||||||
status_t ret;
|
return B_ERROR;
|
||||||
|
|
||||||
|
BPath &destination = state->destination;
|
||||||
|
status_t ret = B_OK;
|
||||||
parser_debug("File: %s WriteToPath() called!\n", fPath.String());
|
parser_debug("File: %s WriteToPath() called!\n", fPath.String());
|
||||||
|
|
||||||
|
BFile file;
|
||||||
|
if (state->status == B_NO_INIT || destination.InitCheck() != B_OK) {
|
||||||
ret = InitPath(path, &destination);
|
ret = InitPath(path, &destination);
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
BFile file(destination.Path(),
|
|
||||||
B_WRITE_ONLY | B_CREATE_FILE | B_FAIL_IF_EXISTS);
|
|
||||||
ret = file.InitCheck();
|
|
||||||
if (ret == B_FILE_EXISTS) {
|
|
||||||
int32 selection = ItemExists(destination.Leaf());
|
|
||||||
switch (selection) {
|
|
||||||
case 0:
|
|
||||||
ret = file.SetTo(destination.Path(),
|
ret = file.SetTo(destination.Path(),
|
||||||
B_WRITE_ONLY | B_ERASE_FILE);
|
B_WRITE_ONLY | B_CREATE_FILE | B_FAIL_IF_EXISTS);
|
||||||
if (ret != B_OK)
|
if (ret == B_ENTRY_NOT_FOUND) {
|
||||||
return ret;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
return B_OK;
|
|
||||||
default:
|
|
||||||
return B_FILE_EXISTS;
|
|
||||||
}
|
|
||||||
} else if (ret == B_ENTRY_NOT_FOUND) {
|
|
||||||
BPath directory;
|
BPath directory;
|
||||||
destination.GetParent(&directory);
|
destination.GetParent(&directory);
|
||||||
if (create_directory(directory.Path(), kDefaultMode) != B_OK)
|
if (create_directory(directory.Path(), kDefaultMode) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
ret = file.SetTo(destination.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
ret = file.SetTo(destination.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
||||||
|
} else if (ret == B_FILE_EXISTS)
|
||||||
|
state->status = B_FILE_EXISTS;
|
||||||
|
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
} else if (ret != B_OK)
|
}
|
||||||
|
|
||||||
|
if (state->status == B_FILE_EXISTS) {
|
||||||
|
switch (state->policy) {
|
||||||
|
case P_EXISTS_OVERWRITE:
|
||||||
|
ret = file.SetTo(destination.Path(),
|
||||||
|
B_WRITE_ONLY | B_ERASE_FILE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_EXISTS_NONE:
|
||||||
|
case P_EXISTS_ASK:
|
||||||
|
ret = B_FILE_EXISTS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_EXISTS_SKIP:
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
parser_debug(" File created!\n");
|
parser_debug(" File created!\n");
|
||||||
@@ -637,9 +635,6 @@ PackageFile::WriteToPath(const char *path, BPath *final)
|
|||||||
delete[] temp;
|
delete[] temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (final)
|
|
||||||
*final = destination;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,7 +652,8 @@ PackageFile::ItemKind()
|
|||||||
PackageLink::PackageLink(BFile *parent, const BString &path,
|
PackageLink::PackageLink(BFile *parent, const BString &path,
|
||||||
const BString &link, uint8 type, uint32 ctime, uint32 mtime,
|
const BString &link, uint8 type, uint32 ctime, uint32 mtime,
|
||||||
uint32 mode, uint64 offset, uint64 size)
|
uint32 mode, uint64 offset, uint64 size)
|
||||||
: PackageItem(parent, path, type, ctime, mtime, offset, size),
|
:
|
||||||
|
PackageItem(parent, path, type, ctime, mtime, offset, size),
|
||||||
fMode(mode),
|
fMode(mode),
|
||||||
fLink(link)
|
fLink(link)
|
||||||
{
|
{
|
||||||
@@ -665,12 +661,22 @@ PackageLink::PackageLink(BFile *parent, const BString &path,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageLink::WriteToPath(const char *path, BPath *final)
|
PackageLink::WriteToPath(const char *path, ItemState *state)
|
||||||
{
|
{
|
||||||
|
if (state == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status_t ret = B_OK;
|
||||||
|
BSymLink symlink;
|
||||||
parser_debug("Symlink: %s WriteToPath() called!\n", fPath.String());
|
parser_debug("Symlink: %s WriteToPath() called!\n", fPath.String());
|
||||||
|
|
||||||
BPath destination;
|
BPath &destination = state->destination;
|
||||||
status_t ret = InitPath(path, &destination);
|
BDirectory *dir = &state->parent;
|
||||||
|
|
||||||
|
if (state->status == B_NO_INIT || destination.InitCheck() != B_OK
|
||||||
|
|| dir->InitCheck() != B_OK) {
|
||||||
|
// Not yet initialized
|
||||||
|
ret = InitPath(path, &destination);
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -680,58 +686,63 @@ PackageLink::WriteToPath(const char *path, BPath *final)
|
|||||||
|
|
||||||
BPath dirPath;
|
BPath dirPath;
|
||||||
ret = destination.GetParent(&dirPath);
|
ret = destination.GetParent(&dirPath);
|
||||||
BDirectory dir(dirPath.Path());
|
ret = dir->SetTo(dirPath.Path());
|
||||||
|
|
||||||
ret = dir.InitCheck();
|
|
||||||
if (ret == B_ENTRY_NOT_FOUND) {
|
if (ret == B_ENTRY_NOT_FOUND) {
|
||||||
if ((ret = create_directory(dirPath.Path(), kDefaultMode)) != B_OK) {
|
ret = create_directory(dirPath.Path(), kDefaultMode);
|
||||||
|
if (ret != B_OK) {
|
||||||
parser_debug("create_directory()) failed\n");
|
parser_debug("create_directory()) failed\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret != B_OK) {
|
if (ret != B_OK) {
|
||||||
parser_debug("destination InitCheck failed %s for %s\n", strerror(ret), dirPath.Path());
|
parser_debug("destination InitCheck failed %s for %s\n",
|
||||||
|
strerror(ret), dirPath.Path());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BSymLink symlink;
|
ret = dir->CreateSymLink(destination.Path(), fLink.String(), &symlink);
|
||||||
ret = dir.CreateSymLink(destination.Path(), fLink.String(), &symlink);
|
|
||||||
if (ret == B_FILE_EXISTS) {
|
if (ret == B_FILE_EXISTS) {
|
||||||
// We need to check if the existing symlink is pointing at the same path
|
// We need to check if the existing symlink is pointing at the same path
|
||||||
// as our new one - if not, let's prompt the user
|
// as our new one - if not, let's prompt the user
|
||||||
symlink.SetTo(destination.Path());
|
symlink.SetTo(destination.Path());
|
||||||
BPath oldLink;
|
BPath oldLink;
|
||||||
|
|
||||||
ret = symlink.MakeLinkedPath(&dir, &oldLink);
|
ret = symlink.MakeLinkedPath(dir, &oldLink);
|
||||||
chdir(dirPath.Path());
|
chdir(dirPath.Path());
|
||||||
|
|
||||||
if (ret == B_BAD_VALUE || oldLink != fLink.String()) {
|
if (ret == B_BAD_VALUE || oldLink != fLink.String())
|
||||||
// The old symlink is different (or not a symlink) - ask the user
|
state->status = ret = B_FILE_EXISTS;
|
||||||
int32 selection = ItemExists(destination.Leaf());
|
else
|
||||||
switch (selection) {
|
ret = B_OK;
|
||||||
case 0:
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->status == B_FILE_EXISTS) {
|
||||||
|
switch (state->policy) {
|
||||||
|
case P_EXISTS_OVERWRITE:
|
||||||
{
|
{
|
||||||
symlink.Unset();
|
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
ret = entry.SetTo(destination.Path());
|
ret = entry.SetTo(destination.Path());
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
entry.Remove();
|
entry.Remove();
|
||||||
ret = dir.CreateSymLink(destination.Path(), fLink.String(),
|
ret = dir->CreateSymLink(destination.Path(), fLink.String(),
|
||||||
&symlink);
|
&symlink);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
|
||||||
parser_debug("Skipping already existent SymLink\n");
|
case P_EXISTS_NONE:
|
||||||
return B_OK;
|
case P_EXISTS_ASK:
|
||||||
default:
|
|
||||||
ret = B_FILE_EXISTS;
|
ret = B_FILE_EXISTS;
|
||||||
}
|
break;
|
||||||
} else {
|
|
||||||
ret = B_OK;
|
case P_EXISTS_SKIP:
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != B_OK) {
|
if (ret != B_OK) {
|
||||||
parser_debug("CreateSymLink failed\n");
|
parser_debug("CreateSymLink failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
@@ -759,10 +770,6 @@ PackageLink::WriteToPath(const char *path, BPath *final)
|
|||||||
ret = HandleAttributes(&destination, &symlink, "LnDa");
|
ret = HandleAttributes(&destination, &symlink, "LnDa");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (final) {
|
|
||||||
*final = destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Haiku, Inc.
|
* Copyright 2007-2009, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Author:
|
* Author:
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
@@ -32,10 +33,38 @@ enum {
|
|||||||
P_USER_PATH
|
P_USER_PATH
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Existing item overwriting policy of a single file
|
||||||
|
enum {
|
||||||
|
P_EXISTS_ASK = 0,
|
||||||
|
P_EXISTS_OVERWRITE,
|
||||||
|
P_EXISTS_SKIP,
|
||||||
|
P_EXISTS_ABORT,
|
||||||
|
P_EXISTS_NONE
|
||||||
|
};
|
||||||
|
|
||||||
extern status_t inflate_data(uint8* in, uint32 inSize, uint8* out,
|
extern status_t inflate_data(uint8* in, uint32 inSize, uint8* out,
|
||||||
uint32 outSize);
|
uint32 outSize);
|
||||||
|
|
||||||
|
|
||||||
|
struct ItemState {
|
||||||
|
ItemState() : policy(P_EXISTS_NONE), status(B_NO_INIT) {}
|
||||||
|
~ItemState() {}
|
||||||
|
|
||||||
|
inline void Reset(int32 currentPolicy)
|
||||||
|
{
|
||||||
|
destination.Unset();
|
||||||
|
parent.Unset();
|
||||||
|
status = B_NO_INIT;
|
||||||
|
policy = currentPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPath destination;
|
||||||
|
BDirectory parent;
|
||||||
|
uint8 policy;
|
||||||
|
status_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class PackageItem {
|
class PackageItem {
|
||||||
public:
|
public:
|
||||||
PackageItem(BFile* parent, const BString& path,
|
PackageItem(BFile* parent, const BString& path,
|
||||||
@@ -44,14 +73,13 @@ public:
|
|||||||
virtual ~PackageItem();
|
virtual ~PackageItem();
|
||||||
|
|
||||||
virtual status_t WriteToPath(const char* path = NULL,
|
virtual status_t WriteToPath(const char* path = NULL,
|
||||||
BPath* final = NULL) = 0;
|
ItemState *state = NULL) = 0;
|
||||||
virtual void SetTo(BFile* parent, const BString& path,
|
virtual void SetTo(BFile* parent, const BString& path,
|
||||||
uint8 type, uint32 ctime, uint32 mtime,
|
uint8 type, uint32 ctime, uint32 mtime,
|
||||||
uint64 offset = 0, uint64 size = 0);
|
uint64 offset = 0, uint64 size = 0);
|
||||||
|
virtual const char* ItemKind() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const char* ItemKind() = 0;
|
|
||||||
int32 ItemExists(const char* name);
|
|
||||||
status_t InitPath(const char* path, BPath* destination);
|
status_t InitPath(const char* path, BPath* destination);
|
||||||
status_t HandleAttributes(BPath* destination, BNode* node,
|
status_t HandleAttributes(BPath* destination, BNode* node,
|
||||||
const char* header);
|
const char* header);
|
||||||
@@ -84,9 +112,7 @@ public:
|
|||||||
uint64 offset = 0, uint64 size = 0);
|
uint64 offset = 0, uint64 size = 0);
|
||||||
|
|
||||||
virtual status_t WriteToPath(const char* path = NULL,
|
virtual status_t WriteToPath(const char* path = NULL,
|
||||||
BPath* final = NULL);
|
ItemState *state = NULL);
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual const char* ItemKind();
|
virtual const char* ItemKind();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,9 +126,7 @@ public:
|
|||||||
const BString& signature, uint32 mode);
|
const BString& signature, uint32 mode);
|
||||||
|
|
||||||
virtual status_t WriteToPath(const char* path = NULL,
|
virtual status_t WriteToPath(const char* path = NULL,
|
||||||
BPath* final = NULL);
|
ItemState *state = NULL);
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual const char* ItemKind();
|
virtual const char* ItemKind();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -123,9 +147,7 @@ public:
|
|||||||
uint64 size = 0);
|
uint64 size = 0);
|
||||||
|
|
||||||
virtual status_t WriteToPath(const char* path = NULL,
|
virtual status_t WriteToPath(const char* path = NULL,
|
||||||
BPath* final = NULL);
|
ItemState *state = NULL);
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual const char* ItemKind();
|
virtual const char* ItemKind();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Haiku, Inc.
|
* Copyright 2007-2009, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Author:
|
* Author:
|
||||||
@@ -305,8 +305,9 @@ PackageView::Install()
|
|||||||
|
|
||||||
// Install files and directories
|
// Install files and directories
|
||||||
PackageItem *iter;
|
PackageItem *iter;
|
||||||
BPath installedTo;
|
ItemState state;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
int32 choice;
|
||||||
BString label;
|
BString label;
|
||||||
|
|
||||||
packageInfo.SetName(fInfo.GetName());
|
packageInfo.SetName(fInfo.GetName());
|
||||||
@@ -322,20 +323,35 @@ PackageView::Install()
|
|||||||
packageInfo.SetDescription(description.String());
|
packageInfo.SetDescription(description.String());
|
||||||
packageInfo.SetSpaceNeeded(type->space_needed);
|
packageInfo.SetSpaceNeeded(type->space_needed);
|
||||||
|
|
||||||
|
fItemExistsPolicy = P_EXISTS_NONE;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
state.Reset(fItemExistsPolicy); // Reset the current item state
|
||||||
iter = static_cast<PackageItem *>(type->items.ItemAt(i));
|
iter = static_cast<PackageItem *>(type->items.ItemAt(i));
|
||||||
err = iter->WriteToPath(fCurrentPath.Path(), &installedTo);
|
|
||||||
|
err = iter->WriteToPath(fCurrentPath.Path(), &state);
|
||||||
|
if (err == B_FILE_EXISTS) {
|
||||||
|
// Writing to path failed because path already exists - ask the user
|
||||||
|
// what to do and retry the writing process
|
||||||
|
choice = _ItemExists(*iter, state.destination);
|
||||||
|
if (choice != P_EXISTS_ABORT) {
|
||||||
|
state.policy = choice;
|
||||||
|
err = iter->WriteToPath(fCurrentPath.Path(), &state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
fprintf(stderr, "Error while writing path %s\n", fCurrentPath.Path());
|
fprintf(stderr, "Error while writing path %s\n", fCurrentPath.Path());
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fStatusWindow->Stopped())
|
if (fStatusWindow->Stopped())
|
||||||
return B_FILE_EXISTS;
|
return B_FILE_EXISTS;
|
||||||
label = "";
|
label = "";
|
||||||
label << (uint32)(i + 1) << " of " << (uint32)n;
|
label << (uint32)(i + 1) << " of " << (uint32)n;
|
||||||
fStatusWindow->StageStep(1, NULL, label.String());
|
fStatusWindow->StageStep(1, NULL, label.String());
|
||||||
|
|
||||||
packageInfo.AddItem(installedTo.Path());
|
packageInfo.AddItem(state.destination.Path());
|
||||||
}
|
}
|
||||||
|
|
||||||
fStatusWindow->StageStep(1, "Finishing installation", "");
|
fStatusWindow->StageStep(1, "Finishing installation", "");
|
||||||
@@ -534,6 +550,68 @@ PackageView::_InitProfiles()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
PackageView::_ItemExists(PackageItem &item, BPath &path)
|
||||||
|
{
|
||||||
|
int32 choice = P_EXISTS_NONE;
|
||||||
|
|
||||||
|
switch (fItemExistsPolicy) {
|
||||||
|
case P_EXISTS_OVERWRITE:
|
||||||
|
choice = P_EXISTS_OVERWRITE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_EXISTS_SKIP:
|
||||||
|
choice = P_EXISTS_SKIP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_EXISTS_ASK:
|
||||||
|
case P_EXISTS_NONE:
|
||||||
|
{
|
||||||
|
BString alertString = T("The ");
|
||||||
|
|
||||||
|
alertString << item.ItemKind() << T(" named \'") << path.Leaf() << "\' ";
|
||||||
|
alertString << T("already exists in the given path. Should the "
|
||||||
|
"existing file be replaced with the one from this package?");
|
||||||
|
|
||||||
|
BAlert *alert = new BAlert(T("file_exists"), alertString.String(),
|
||||||
|
T("Yes"), T("No"), T("Abort"));
|
||||||
|
|
||||||
|
choice = alert->Go();
|
||||||
|
switch (choice) {
|
||||||
|
case 0:
|
||||||
|
choice = P_EXISTS_OVERWRITE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
choice = P_EXISTS_SKIP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return P_EXISTS_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fItemExistsPolicy == P_EXISTS_NONE) {
|
||||||
|
// TODO: Maybe add 'No, but ask again' type of choice as well?
|
||||||
|
alertString = T("Should this decision be remembered and all "
|
||||||
|
"existing files encountered in the future be ");
|
||||||
|
alertString << ((choice == P_EXISTS_OVERWRITE)
|
||||||
|
? T("replaced?") : T("skipped?"));
|
||||||
|
|
||||||
|
alert = new BAlert(T("policy_decision"), alertString.String(),
|
||||||
|
T("Yes"), T("No"));
|
||||||
|
|
||||||
|
int32 decision = alert->Go();
|
||||||
|
if (decision == 0)
|
||||||
|
fItemExistsPolicy = choice;
|
||||||
|
else
|
||||||
|
fItemExistsPolicy = P_EXISTS_ASK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageView::_GroupChanged(int32 index)
|
PackageView::_GroupChanged(int32 index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Haiku, Inc.
|
* Copyright 2007-2009, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Author:
|
* Author:
|
||||||
@@ -42,6 +42,7 @@ class PackageView : public BView {
|
|||||||
private:
|
private:
|
||||||
void _InitView();
|
void _InitView();
|
||||||
void _InitProfiles();
|
void _InitProfiles();
|
||||||
|
int32 _ItemExists(PackageItem &item, BPath &path);
|
||||||
|
|
||||||
status_t _GroupChanged(int32 index);
|
status_t _GroupChanged(int32 index);
|
||||||
|
|
||||||
@@ -54,6 +55,7 @@ class PackageView : public BView {
|
|||||||
BFilePanel *fOpenPanel;
|
BFilePanel *fOpenPanel;
|
||||||
BPath fCurrentPath;
|
BPath fCurrentPath;
|
||||||
uint32 fCurrentType;
|
uint32 fCurrentType;
|
||||||
|
int32 fItemExistsPolicy;
|
||||||
|
|
||||||
PackageInfo fInfo;
|
PackageInfo fInfo;
|
||||||
PackageStatus *fStatusWindow;
|
PackageStatus *fStatusWindow;
|
||||||
|
|||||||
Reference in New Issue
Block a user