Work in progress: Tiling window placement, screen-center-preferring with semi-fixed slots. Not sure I like it. (It looks nice as long as the windows stay equally sized, which they don't.) Settings weren't used anymore, and could be removed. Clean-ups. Changed archive creation to not update an existing archive, but instead create a new archive with a slightly altered filename along-side the existing file. Lock added to safe-guard pipe redirection. A window's Stop/Continue alert now shows the name of the archive in making. I added some code to show and select the archive in Tracker, post-creation, but it does not work reliably, so I've disabled it for now.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34044 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
aece77090d
commit
714236b802
@ -6,8 +6,6 @@ Application ZipOMatic-Z :
|
||||
GenericThread.cpp
|
||||
ZipOMatic.cpp
|
||||
ZipOMaticActivity.cpp
|
||||
ZipOMaticMisc.cpp
|
||||
ZipOMaticSettings.cpp
|
||||
ZipOMaticWindow.cpp
|
||||
ZipperThread.cpp
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Roster.h>
|
||||
#include <Screen.h>
|
||||
#include <TrackerAddOnAppLaunch.h>
|
||||
|
||||
#include "ZipOMaticMisc.h"
|
||||
@ -31,45 +30,27 @@ main()
|
||||
ZipOMatic::ZipOMatic()
|
||||
:
|
||||
BApplication(ZIPOMATIC_APP_SIG),
|
||||
fSettings(),
|
||||
fGotRefs(false),
|
||||
fInvoker(new BInvoker(new BMessage(ZIPPO_QUIT_OR_CONTINUE), NULL, this)),
|
||||
fWindowFrame(200, 200, 430, 310)
|
||||
fInvoker(new BInvoker(new BMessage(ZIPPO_QUIT_OR_CONTINUE), NULL, this))
|
||||
{
|
||||
status_t status = _ReadSettings();
|
||||
|
||||
if (status != B_OK)
|
||||
ErrorMessage("_ReadSettings()", status);
|
||||
}
|
||||
|
||||
|
||||
ZipOMatic::~ZipOMatic()
|
||||
{
|
||||
status_t status = _WriteSettings();
|
||||
|
||||
if (status != B_OK)
|
||||
ErrorMessage("_WriteSettings()", status);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZipOMatic::RefsReceived(BMessage* message)
|
||||
{
|
||||
message->RemoveName("dir_ref");
|
||||
|
||||
entry_ref ref;
|
||||
if (message->FindRef("refs", &ref) != B_OK) {
|
||||
if (!IsLaunching())
|
||||
PostMessage(B_SILENT_RELAUNCH);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsLaunching())
|
||||
if (message->FindRef("refs", &ref) == B_OK) {
|
||||
_UseExistingOrCreateNewWindow(message);
|
||||
fGotRefs = true;
|
||||
|
||||
BMessage* msg = new BMessage(*message);
|
||||
|
||||
_UseExistingOrCreateNewWindow(msg);
|
||||
} else if (!IsLaunching()) {
|
||||
PostMessage(B_SILENT_RELAUNCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -87,9 +68,6 @@ ZipOMatic::MessageReceived(BMessage* message)
|
||||
switch (message->what) {
|
||||
case ZIPPO_WINDOW_QUIT:
|
||||
{
|
||||
BRect frame;
|
||||
if (message->FindRect("frame", &frame) == B_OK)
|
||||
fWindowFrame = frame;
|
||||
snooze(200000);
|
||||
if (CountWindows() == 0)
|
||||
Quit();
|
||||
@ -208,43 +186,42 @@ void
|
||||
ZipOMatic::_UseExistingOrCreateNewWindow(BMessage* message)
|
||||
{
|
||||
int32 windowCount = 0;
|
||||
ZippoWindow* window;
|
||||
bool foundNonBusyWindow = false;
|
||||
BWindow* bWindow;
|
||||
ZippoWindow* zWindow;
|
||||
BList list;
|
||||
|
||||
while (1) {
|
||||
window = dynamic_cast<ZippoWindow*>(WindowAt(windowCount++));
|
||||
if (window == NULL)
|
||||
bWindow = WindowAt(windowCount++);
|
||||
if (bWindow == NULL)
|
||||
break;
|
||||
|
||||
if (window->Lock()) {
|
||||
if (!window->IsZipping()) {
|
||||
foundNonBusyWindow = true;
|
||||
zWindow = dynamic_cast<ZippoWindow*>(bWindow);
|
||||
if (zWindow == NULL)
|
||||
continue;
|
||||
|
||||
list.AddItem(zWindow);
|
||||
|
||||
if (zWindow->Lock()) {
|
||||
if (!zWindow->IsZipping()) {
|
||||
if (message != NULL)
|
||||
window->PostMessage(message);
|
||||
window->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
window->Activate();
|
||||
window->Unlock();
|
||||
break;
|
||||
zWindow->PostMessage(message);
|
||||
zWindow->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
zWindow->Activate();
|
||||
zWindow->Unlock();
|
||||
return;
|
||||
}
|
||||
window->Unlock();
|
||||
zWindow->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundNonBusyWindow)
|
||||
{
|
||||
BScreen screen;
|
||||
fWindowFrame.OffsetBy(screen.Frame().LeftTop());
|
||||
|
||||
_CascadeOnFrameCollision(&fWindowFrame);
|
||||
if(!screen.Frame().Contains(fWindowFrame)) {
|
||||
fWindowFrame.OffsetTo(screen.Frame().LeftTop());
|
||||
fWindowFrame.OffsetBy(20,45);
|
||||
// TODO: replace with CenterOnScreen()
|
||||
if (message) {
|
||||
zWindow = new ZippoWindow(list);
|
||||
zWindow->PostMessage(message);
|
||||
} else {
|
||||
zWindow = new ZippoWindow(list, true);
|
||||
}
|
||||
|
||||
ZippoWindow * window = new ZippoWindow(fWindowFrame, message);
|
||||
window->Show();
|
||||
}
|
||||
zWindow->Show();
|
||||
}
|
||||
|
||||
|
||||
@ -282,93 +259,3 @@ ZipOMatic::_StopZipping()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZipOMatic::_ReadSettings()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.SetTo("zipomatic.msg");
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.ReadSettings();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BRect frame;
|
||||
status = fSettings.FindRect("frame", &frame);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
fWindowFrame = frame;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZipOMatic::_WriteSettings()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.MakeEmpty();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.AddRect("frame", fWindowFrame);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.WriteSettings();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZipOMatic::_CascadeOnFrameCollision(BRect* frame)
|
||||
{
|
||||
BWindow* window;
|
||||
ZippoWindow* zippo;
|
||||
BList list;
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
window = WindowAt(i);
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
zippo = dynamic_cast<ZippoWindow*>(window);
|
||||
if (zippo == NULL)
|
||||
continue;
|
||||
|
||||
list.AddItem(zippo);
|
||||
}
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
zippo = static_cast<ZippoWindow*>(list.ItemAt(i));
|
||||
if (zippo == NULL)
|
||||
break;
|
||||
|
||||
if (zippo->Lock()) {
|
||||
if (frame->LeftTop() == zippo->Frame().LeftTop())
|
||||
frame->OffsetBy(20, 20);
|
||||
zippo->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,6 @@
|
||||
#include <Application.h>
|
||||
#include <Invoker.h>
|
||||
#include <Message.h>
|
||||
#include <Rect.h>
|
||||
|
||||
#include "ZipOMaticSettings.h"
|
||||
|
||||
|
||||
class ZipOMatic : public BApplication
|
||||
@ -22,18 +19,13 @@ public:
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
status_t _ReadSettings();
|
||||
status_t _WriteSettings();
|
||||
void _CascadeOnFrameCollision(BRect* frame);
|
||||
void _SilentRelaunch();
|
||||
void _UseExistingOrCreateNewWindow(BMessage*
|
||||
message = NULL);
|
||||
void _StopZipping();
|
||||
|
||||
ZippoSettings fSettings;
|
||||
bool fGotRefs;
|
||||
BInvoker* fInvoker;
|
||||
BRect fWindowFrame;
|
||||
};
|
||||
|
||||
#endif // _ZIPOMATIC_H_
|
||||
|
@ -103,10 +103,6 @@ Activity::Draw(BRect rect)
|
||||
BRect bitmapRect = fBitmap->Bounds();
|
||||
|
||||
if (bitmapRect != viewRect) {
|
||||
printf("Activity::Draw(): bitmapRect != viewRect\n");
|
||||
bitmapRect.PrintToStream();
|
||||
viewRect.PrintToStream();
|
||||
|
||||
delete fBitmap;
|
||||
_CreateBitmap();
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jonas Sundström, jonas@kirilla.com
|
||||
*/
|
||||
|
||||
|
||||
#include "ZipOMaticMisc.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
|
||||
status_t
|
||||
FindAndCreateDirectory(directory_which which, BVolume* volume,
|
||||
const char* relativePath, BPath* fullPath)
|
||||
{
|
||||
BPath path;
|
||||
status_t status = find_directory(which, &path, true, volume);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (relativePath != NULL) {
|
||||
path.Append(relativePath);
|
||||
|
||||
mode_t mask = umask(0);
|
||||
umask(mask);
|
||||
|
||||
status = create_directory(path.Path(), mask);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (fullPath != NULL) {
|
||||
status = fullPath->SetTo(path.Path());
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ErrorMessage(const char* text, int32 status)
|
||||
{
|
||||
PRINT(("%s: %s\n", text, strerror(status)));
|
||||
}
|
||||
|
@ -9,12 +9,6 @@
|
||||
#define ZIPOMATIC_MISC_H
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <Volume.h>
|
||||
|
||||
|
||||
#define ZIPOMATIC_APP_SIG "application/x-vnd.haiku.zip-o-matic"
|
||||
|
||||
#define ZIPPO_WINDOW_QUIT 'winq'
|
||||
@ -24,11 +18,6 @@
|
||||
#define ZIPPO_TASK_DESCRIPTION 'strt'
|
||||
#define ZIPPO_LINE_OF_STDOUT 'outp'
|
||||
|
||||
status_t FindAndCreateDirectory(directory_which which,
|
||||
BVolume* volume = NULL, const char* relativePath = NULL,
|
||||
BPath* fullPath = NULL);
|
||||
|
||||
void ErrorMessage(const char* text, int32 status);
|
||||
|
||||
#endif // ZIPOMATIC_MISC_H
|
||||
|
||||
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jonas Sundström, jonas@kirilla.com
|
||||
*/
|
||||
|
||||
// TODO: proper locking <<---------
|
||||
|
||||
|
||||
#include "ZipOMaticSettings.h"
|
||||
|
||||
#include <Debug.h>
|
||||
#include <Directory.h>
|
||||
#include <File.h>
|
||||
#include <Path.h>
|
||||
#include <VolumeRoster.h>
|
||||
|
||||
#include "ZipOMaticMisc.h"
|
||||
|
||||
|
||||
ZippoSettings::ZippoSettings()
|
||||
:
|
||||
fBaseDir(B_USER_SETTINGS_DIRECTORY)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
ZippoSettings::ZippoSettings(BMessage& message)
|
||||
:
|
||||
BMessage(message),
|
||||
fBaseDir(B_USER_SETTINGS_DIRECTORY)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
ZippoSettings::~ZippoSettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoSettings::SetTo(const char* filename, BVolume* volume,
|
||||
directory_which baseDir, const char* relativePath)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
fBaseDir = baseDir;
|
||||
fRelativePath = relativePath;
|
||||
fFilename = filename;
|
||||
|
||||
if (volume == NULL) {
|
||||
BVolumeRoster volumeRoster;
|
||||
volumeRoster.GetBootVolume(&fVolume);
|
||||
} else {
|
||||
fVolume = *volume;
|
||||
}
|
||||
|
||||
status = fVolume.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return InitCheck();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoSettings::InitCheck()
|
||||
{
|
||||
BFile file;
|
||||
return _GetSettingsFile(&file, B_READ_ONLY | B_CREATE_FILE);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoSettings::ReadSettings()
|
||||
{
|
||||
BFile file;
|
||||
status_t status = _GetSettingsFile(&file, B_READ_ONLY);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return Unflatten(&file);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoSettings::WriteSettings()
|
||||
{
|
||||
BFile file;
|
||||
status_t status = _GetSettingsFile(&file, B_WRITE_ONLY | B_ERASE_FILE);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return Flatten(&file);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoSettings::_GetSettingsFile(BFile* file, uint32 openMode)
|
||||
{
|
||||
BPath path;
|
||||
status_t status = FindAndCreateDirectory(fBaseDir, &fVolume,
|
||||
fRelativePath.String(), &path);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = path.Append(fFilename.String());
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return file->SetTo(path.Path(), openMode);
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jonas Sundström, jonas@kirilla.com
|
||||
*/
|
||||
#ifndef _ZIPOMATIC_SETTINGS_H
|
||||
#define _ZIPOMATIC_SETTINGS_H
|
||||
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
#include <Volume.h>
|
||||
|
||||
|
||||
class ZippoSettings : public BMessage {
|
||||
public:
|
||||
ZippoSettings();
|
||||
ZippoSettings(BMessage& message);
|
||||
~ZippoSettings();
|
||||
|
||||
status_t SetTo(const char* filename, BVolume* volume = NULL,
|
||||
directory_which baseDir =
|
||||
B_USER_SETTINGS_DIRECTORY,
|
||||
const char* relativePath = NULL);
|
||||
status_t InitCheck();
|
||||
|
||||
status_t ReadSettings();
|
||||
status_t WriteSettings();
|
||||
|
||||
private:
|
||||
status_t _GetSettingsFile(BFile* file, uint32 openMode);
|
||||
|
||||
BVolume fVolume;
|
||||
directory_which fBaseDir;
|
||||
BString fRelativePath;
|
||||
BString fFilename;
|
||||
};
|
||||
|
||||
#endif // _ZIPOMATIC_SETTINGS_H
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Path.h>
|
||||
#include <Roster.h>
|
||||
#include <Screen.h>
|
||||
#include <SeparatorView.h>
|
||||
#include <String.h>
|
||||
|
||||
@ -30,12 +31,13 @@
|
||||
#include "ZipperThread.h"
|
||||
|
||||
|
||||
ZippoWindow::ZippoWindow(BRect frame, BMessage* refs)
|
||||
ZippoWindow::ZippoWindow(BList windowList, bool keepOpen)
|
||||
:
|
||||
BWindow(frame, "Zip-O-Matic", B_TITLED_WINDOW,
|
||||
BWindow(BRect(0, 0, 0, 0), "Zip-O-Matic", B_TITLED_WINDOW,
|
||||
B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE),
|
||||
fWindowList(windowList),
|
||||
fThread(NULL),
|
||||
fWindowGotRefs(false),
|
||||
fKeepOpen(keepOpen),
|
||||
fZippingWasStopped(false),
|
||||
fFileCount(0),
|
||||
fWindowInvoker(new BInvoker(new BMessage(ZIPPO_QUIT_OR_CONTINUE), NULL,
|
||||
@ -70,10 +72,7 @@ ZippoWindow::ZippoWindow(BRect frame, BMessage* refs)
|
||||
.End()
|
||||
.End();
|
||||
|
||||
if (refs != NULL) {
|
||||
fWindowGotRefs = true;
|
||||
_StartZipping(refs);
|
||||
}
|
||||
_FindBestPlacement();
|
||||
}
|
||||
|
||||
|
||||
@ -88,9 +87,6 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case B_REFS_RECEIVED:
|
||||
_StartZipping(message);
|
||||
break;
|
||||
|
||||
case B_SIMPLE_DATA:
|
||||
if (IsZipping()) {
|
||||
message->what = B_REFS_RECEIVED;
|
||||
@ -125,8 +121,11 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
case ZIPPO_TASK_DESCRIPTION:
|
||||
{
|
||||
BString string;
|
||||
if (message->FindString("archive_filename", &string) == B_OK)
|
||||
if (message->FindString("archive_filename", &string) == B_OK) {
|
||||
fArchiveName = string;
|
||||
string.Prepend("Creating archive: ");
|
||||
fArchiveNameView->SetText(string.String());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -202,8 +201,11 @@ ZippoWindow::QuitRequested()
|
||||
fThread->SuspendExternalZip();
|
||||
fActivityView->Pause();
|
||||
|
||||
BAlert* alert = new BAlert("Stop or Continue",
|
||||
"Are you sure you want to stop creating this archive?", "Stop",
|
||||
BString message;
|
||||
message << "Are you sure you want to stop creating this archive?\n\n";
|
||||
message << "Filename: " << fArchiveName.String() << "\n";
|
||||
|
||||
BAlert* alert = new BAlert(NULL, message.String(), "Stop",
|
||||
"Continue", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||
alert->Go(fWindowInvoker);
|
||||
|
||||
@ -261,7 +263,155 @@ ZippoWindow::IsZipping()
|
||||
void
|
||||
ZippoWindow::_CloseWindowOrKeepOpen()
|
||||
{
|
||||
if (fWindowGotRefs)
|
||||
if (!fKeepOpen)
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZippoWindow::_FindBestPlacement()
|
||||
{
|
||||
CenterOnScreen();
|
||||
|
||||
BScreen screen;
|
||||
BRect centeredRect = Frame();
|
||||
BRect tryRect = centeredRect;
|
||||
BList tryRectList;
|
||||
|
||||
if (!screen.Frame().Contains(centeredRect))
|
||||
return;
|
||||
|
||||
// build a list of possible locations
|
||||
tryRectList.AddItem(new BRect(centeredRect));
|
||||
|
||||
// up and left
|
||||
direction primaryDirection = up;
|
||||
while (true) {
|
||||
_OffsetRect(&tryRect, primaryDirection);
|
||||
|
||||
if (!screen.Frame().Contains(tryRect))
|
||||
_OffscreenBounceBack(&tryRect, &primaryDirection, left);
|
||||
|
||||
if (!screen.Frame().Contains(tryRect))
|
||||
break;
|
||||
|
||||
tryRectList.AddItem(new BRect(tryRect));
|
||||
}
|
||||
|
||||
// down and right
|
||||
primaryDirection = down;
|
||||
tryRect = centeredRect;
|
||||
while (true) {
|
||||
_OffsetRect(&tryRect, primaryDirection);
|
||||
|
||||
if (!screen.Frame().Contains(tryRect))
|
||||
_OffscreenBounceBack(&tryRect, &primaryDirection, right);
|
||||
|
||||
if (!screen.Frame().Contains(tryRect))
|
||||
break;
|
||||
|
||||
tryRectList.AddItem(new BRect(tryRect));
|
||||
}
|
||||
|
||||
// remove rects that overlap an existing window
|
||||
for (int32 i = 0;; i++) {
|
||||
BWindow* win = static_cast<BWindow*>(fWindowList.ItemAt(i));
|
||||
if (win == NULL)
|
||||
break;
|
||||
|
||||
ZippoWindow* window = dynamic_cast<ZippoWindow*>(win);
|
||||
if (window == NULL)
|
||||
continue;
|
||||
|
||||
if (window == this)
|
||||
continue;
|
||||
|
||||
if (window->Lock()) {
|
||||
BRect frame = window->Frame();
|
||||
for (int32 m = 0;; m++) {
|
||||
BRect* rect = static_cast<BRect*>(tryRectList.ItemAt(m));
|
||||
if (rect == NULL)
|
||||
break;
|
||||
|
||||
if (frame.Intersects(*rect)) {
|
||||
tryRectList.RemoveItem(m);
|
||||
delete rect;
|
||||
m--;
|
||||
}
|
||||
}
|
||||
window->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// find nearest rect
|
||||
bool gotRect = false;
|
||||
BRect nearestRect(0, 0, 0, 0);
|
||||
|
||||
while (true) {
|
||||
BRect* rect = static_cast<BRect*>(tryRectList.RemoveItem((int32)0));
|
||||
if (rect == NULL)
|
||||
break;
|
||||
|
||||
nearestRect = _NearestRect(centeredRect, nearestRect, *rect);
|
||||
gotRect = true;
|
||||
delete rect;
|
||||
}
|
||||
|
||||
if (gotRect)
|
||||
MoveTo(nearestRect.LeftTop());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZippoWindow::_OffsetRect(BRect* rect, direction whereTo)
|
||||
{
|
||||
float width = rect->Width();
|
||||
float height = rect->Height();
|
||||
|
||||
switch (whereTo) {
|
||||
case up:
|
||||
rect->OffsetBy(0, -(height * 1.5));
|
||||
break;
|
||||
|
||||
case down:
|
||||
rect->OffsetBy(0, height * 1.5);
|
||||
break;
|
||||
|
||||
case left:
|
||||
rect->OffsetBy(-(width * 1.5), 0);
|
||||
break;
|
||||
|
||||
case right:
|
||||
rect->OffsetBy(width * 1.5, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZippoWindow::_OffscreenBounceBack(BRect* rect, direction* primaryDirection,
|
||||
direction secondaryDirection)
|
||||
{
|
||||
if (*primaryDirection == up) {
|
||||
*primaryDirection = down;
|
||||
} else {
|
||||
*primaryDirection = up;
|
||||
}
|
||||
|
||||
_OffsetRect(rect, *primaryDirection);
|
||||
_OffsetRect(rect, secondaryDirection);
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
ZippoWindow::_NearestRect(BRect goalRect, BRect a, BRect b)
|
||||
{
|
||||
double aSum = fabs(goalRect.left - a.left) + fabs(goalRect.top - a.top);
|
||||
double bSum = fabs(goalRect.left - b.left) + fabs(goalRect.top - b.top);
|
||||
|
||||
if (aSum < bSum)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
|
||||
#include <Button.h>
|
||||
#include <List.h>
|
||||
#include <Rect.h>
|
||||
#include <StringView.h>
|
||||
#include <Window.h>
|
||||
|
||||
@ -10,10 +12,19 @@
|
||||
#include "ZipperThread.h"
|
||||
|
||||
|
||||
enum direction {
|
||||
up,
|
||||
down,
|
||||
left,
|
||||
right
|
||||
};
|
||||
|
||||
|
||||
class ZippoWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
ZippoWindow(BRect frame, BMessage* refs = NULL);
|
||||
ZippoWindow(BList windowList,
|
||||
bool keepOpen = false);
|
||||
~ZippoWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
@ -27,14 +38,24 @@ private:
|
||||
void _StartZipping(BMessage* message);
|
||||
void _CloseWindowOrKeepOpen();
|
||||
|
||||
void _FindBestPlacement();
|
||||
void _OffsetRect(BRect* rect, direction whereTo);
|
||||
void _OffscreenBounceBack(BRect* rect,
|
||||
direction* primaryDirection,
|
||||
direction secondaryDirection);
|
||||
BRect _NearestRect(BRect goalRect, BRect a, BRect b);
|
||||
|
||||
BList fWindowList;
|
||||
|
||||
Activity* fActivityView;
|
||||
BStringView* fArchiveNameView;
|
||||
BStringView* fZipOutputView;
|
||||
BButton* fStopButton;
|
||||
|
||||
ZipperThread* fThread;
|
||||
BString fArchiveName;
|
||||
|
||||
bool fWindowGotRefs;
|
||||
bool fKeepOpen;
|
||||
bool fZippingWasStopped;
|
||||
int32 fFileCount;
|
||||
|
||||
|
@ -12,9 +12,11 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <Locker.h>
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
#include <Volume.h>
|
||||
@ -34,9 +36,6 @@ ZipperThread::ZipperThread(BMessage* refsMessage, BWindow* window)
|
||||
fOutputFile(NULL)
|
||||
{
|
||||
fThreadDataStore = new BMessage(*refsMessage);
|
||||
// leak?
|
||||
// prevents bug with B_SIMPLE_DATA
|
||||
// (drag&drop messages)
|
||||
}
|
||||
|
||||
|
||||
@ -48,9 +47,6 @@ ZipperThread::~ZipperThread()
|
||||
status_t
|
||||
ZipperThread::ThreadStartup()
|
||||
{
|
||||
BString archiveName = "Archive.zip";
|
||||
|
||||
// do all refs have the same parent dir?
|
||||
type_code type = B_REF_TYPE;
|
||||
int32 refCount = 0;
|
||||
entry_ref ref;
|
||||
@ -58,23 +54,17 @@ ZipperThread::ThreadStartup()
|
||||
bool sameFolder = true;
|
||||
|
||||
status_t status = fThreadDataStore->GetInfo("refs", &type, &refCount);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
if (status != B_OK || refCount < 1) {
|
||||
_SendMessageToWindow(ZIPPO_THREAD_EXIT_ERROR);
|
||||
Quit();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
for (int index = 0; index < refCount; index++) {
|
||||
fThreadDataStore->FindRef("refs", index, &ref);
|
||||
|
||||
if (index > 0) {
|
||||
BEntry entry(&ref);
|
||||
if (entry.IsSymLink()) {
|
||||
entry.SetTo(&ref, true);
|
||||
entry_ref target;
|
||||
entry.GetRef(&target);
|
||||
if (lastRef.directory != target.directory) {
|
||||
sameFolder = false;
|
||||
break;
|
||||
}
|
||||
} else if (lastRef.directory != ref.directory) {
|
||||
if (lastRef.directory != ref.directory) {
|
||||
sameFolder = false;
|
||||
break;
|
||||
}
|
||||
@ -82,8 +72,27 @@ ZipperThread::ThreadStartup()
|
||||
lastRef = ref;
|
||||
}
|
||||
|
||||
// change active dir
|
||||
if (sameFolder) {
|
||||
entry_ref dirRef;
|
||||
bool gotDirRef = false;
|
||||
|
||||
status = fThreadDataStore->FindRef("dir_ref", 0, &dirRef);
|
||||
if (status == B_OK) {
|
||||
BEntry dirEntry(&dirRef);
|
||||
BNode dirNode(&dirRef);
|
||||
|
||||
if (dirEntry.InitCheck() == B_OK
|
||||
&& dirEntry.Exists()
|
||||
&& dirNode.InitCheck() == B_OK
|
||||
&& dirNode.IsDirectory())
|
||||
gotDirRef = true;
|
||||
}
|
||||
|
||||
if (gotDirRef) {
|
||||
BEntry entry(&dirRef);
|
||||
BPath path;
|
||||
entry.GetPath(&path);
|
||||
chdir(path.Path());
|
||||
} else if (sameFolder) {
|
||||
BEntry entry(&lastRef);
|
||||
BPath path;
|
||||
entry.GetParent(&entry);
|
||||
@ -95,10 +104,28 @@ ZipperThread::ThreadStartup()
|
||||
chdir(path.Path());
|
||||
}
|
||||
|
||||
// archive filename
|
||||
if (refCount == 1) {
|
||||
BString archiveName;
|
||||
|
||||
if (refCount > 1)
|
||||
archiveName = "Archive";
|
||||
else
|
||||
archiveName = lastRef.name;
|
||||
archiveName += ".zip";
|
||||
|
||||
int index = 1;
|
||||
for (;; index++) {
|
||||
BString tryName = archiveName;
|
||||
|
||||
if (index != 1)
|
||||
tryName << " " << index;
|
||||
|
||||
tryName << ".zip";
|
||||
|
||||
BEntry entry(tryName.String());
|
||||
if (!entry.Exists()) {
|
||||
archiveName = tryName;
|
||||
entry.GetRef(&fOutputEntryRef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32 argc = refCount + 3;
|
||||
@ -108,15 +135,12 @@ ZipperThread::ThreadStartup()
|
||||
argv[1] = strdup("-ry");
|
||||
argv[2] = strdup(archiveName.String());
|
||||
|
||||
// files to zip
|
||||
for (int index = 0; index < refCount; index++) {
|
||||
fThreadDataStore->FindRef("refs", index, &ref);
|
||||
|
||||
if (sameFolder) {
|
||||
// just the file name
|
||||
if (gotDirRef || sameFolder) {
|
||||
argv[3 + index] = strdup(ref.name);
|
||||
} else {
|
||||
// full path
|
||||
BPath path(&ref);
|
||||
BString file = path.Path();
|
||||
argv[3 + index] = strdup(path.Path());
|
||||
@ -138,8 +162,6 @@ ZipperThread::ThreadStartup()
|
||||
if (fOutputFile == NULL)
|
||||
return errno;
|
||||
|
||||
archiveName.Prepend("Creating archive: ");
|
||||
|
||||
_SendMessageToWindow(ZIPPO_TASK_DESCRIPTION, "archive_filename",
|
||||
archiveName.String());
|
||||
_SendMessageToWindow(ZIPPO_LINE_OF_STDOUT, "zip_output",
|
||||
@ -152,8 +174,6 @@ ZipperThread::ThreadStartup()
|
||||
status_t
|
||||
ZipperThread::ExecuteUnit()
|
||||
{
|
||||
// read output from /bin/zip
|
||||
// send it to window
|
||||
char buffer[4096];
|
||||
|
||||
char* output = fgets(buffer, sizeof(buffer) - 1, fOutputFile);
|
||||
@ -185,6 +205,8 @@ ZipperThread::ThreadShutdown()
|
||||
close(fStdOut);
|
||||
close(fStdErr);
|
||||
|
||||
// _SelectInTracker();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -192,7 +214,6 @@ ZipperThread::ThreadShutdown()
|
||||
void
|
||||
ZipperThread::ThreadStartupFailed(status_t status)
|
||||
{
|
||||
ErrorMessage("ZipperThread::ThreadStartupFailed() \n", status);
|
||||
Quit();
|
||||
}
|
||||
|
||||
@ -200,8 +221,6 @@ ZipperThread::ThreadStartupFailed(status_t status)
|
||||
void
|
||||
ZipperThread::ExecuteUnitFailed(status_t status)
|
||||
{
|
||||
ErrorMessage("ZipperThread::ExecuteUnitFailed() \n", status);
|
||||
|
||||
if (status == EOF) {
|
||||
// thread has finished, been quit or killed, we don't know
|
||||
_SendMessageToWindow(ZIPPO_THREAD_EXIT);
|
||||
@ -217,7 +236,8 @@ ZipperThread::ExecuteUnitFailed(status_t status)
|
||||
void
|
||||
ZipperThread::ThreadShutdownFailed(status_t status)
|
||||
{
|
||||
ErrorMessage("ZipperThread::ThreadShutdownFailed() \n", status);
|
||||
fprintf(stderr, "ZipperThread::ThreadShutdownFailed(): %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
|
||||
|
||||
@ -234,8 +254,11 @@ thread_id
|
||||
ZipperThread::_PipeCommand(int argc, const char** argv, int& in, int& out,
|
||||
int& err, const char** envp)
|
||||
{
|
||||
// This function was originally written by Peter Folk <pfolk@uni.uiuc.edu>
|
||||
// and published in the BeDevTalk FAQ
|
||||
static BLocker lock;
|
||||
|
||||
if (lock.Lock()) {
|
||||
// This function was originally written by Peter Folk
|
||||
// <pfolk@uni.uiuc.edu> and published in the BeDevTalk FAQ
|
||||
// http://www.abisoft.com/faq/BeDevTalk_FAQ.html#FAQ-209
|
||||
|
||||
thread_id thread;
|
||||
@ -283,6 +306,8 @@ ZipperThread::_PipeCommand(int argc, const char** argv, int& in, int& out,
|
||||
close(oldOut);
|
||||
dup2(oldErr, STDERR_FILENO);
|
||||
close(oldErr);
|
||||
|
||||
lock.Unlock();
|
||||
return thread;
|
||||
|
||||
err3:
|
||||
@ -295,7 +320,12 @@ err1:
|
||||
close(oldIn);
|
||||
close(oldOut);
|
||||
close(oldErr);
|
||||
|
||||
lock.Unlock();
|
||||
return errno;
|
||||
} else {
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -366,3 +396,123 @@ ZipperThread::WaitOnExternalZip()
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZipperThread::_SelectInTracker(int32 tryNumber)
|
||||
{
|
||||
// work in progress - unreliable - not ready to be used
|
||||
|
||||
entry_ref parentRef;
|
||||
BEntry entry(&fOutputEntryRef);
|
||||
|
||||
if (!entry.Exists())
|
||||
return B_FILE_NOT_FOUND;
|
||||
|
||||
entry.GetParent(&entry);
|
||||
entry.GetRef(&parentRef);
|
||||
|
||||
BMessenger trackerMessenger("application/x-vnd.Be-TRAK");
|
||||
if (!trackerMessenger.IsValid())
|
||||
return B_ERROR;
|
||||
|
||||
BMessage request;
|
||||
BMessage reply;
|
||||
status_t status;
|
||||
|
||||
if (tryNumber == 0) {
|
||||
request.MakeEmpty();
|
||||
request.what = B_REFS_RECEIVED;
|
||||
request.AddRef("refs", &parentRef);
|
||||
trackerMessenger.SendMessage(&request, &reply);
|
||||
}
|
||||
|
||||
if (tryNumber > 20)
|
||||
return B_ERROR;
|
||||
|
||||
snooze(200000);
|
||||
|
||||
// find out the number of Tracker windows
|
||||
request.MakeEmpty();
|
||||
request.what = B_COUNT_PROPERTIES;
|
||||
request.AddSpecifier("Window");
|
||||
reply.MakeEmpty();
|
||||
|
||||
status = trackerMessenger.SendMessage(&request, &reply);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
int32 windowCount;
|
||||
status = reply.FindInt32("result", &windowCount);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// find a likely parent window
|
||||
bool foundWindow = false;
|
||||
int32 index = 0;
|
||||
for (; index < windowCount; index++) {
|
||||
request.MakeEmpty();
|
||||
request.what = B_GET_PROPERTY;
|
||||
request.AddSpecifier("Path");
|
||||
request.AddSpecifier("Poses");
|
||||
request.AddSpecifier("Window", index);
|
||||
reply.MakeEmpty();
|
||||
|
||||
status = trackerMessenger.SendMessage(&request, &reply);
|
||||
if (status != B_OK)
|
||||
continue;
|
||||
|
||||
entry_ref windowRef;
|
||||
status = reply.FindRef("result", &windowRef);
|
||||
if (status != B_OK)
|
||||
continue;
|
||||
|
||||
if (windowRef == parentRef) {
|
||||
foundWindow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundWindow)
|
||||
return _SelectInTracker(tryNumber + 1);
|
||||
|
||||
// find entry_ref in window - a newly opened window might
|
||||
// be filling and the entry_ref perhaps not there yet?
|
||||
request.MakeEmpty();
|
||||
request.what = B_GET_PROPERTY;
|
||||
request.AddSpecifier("Entry");
|
||||
request.AddSpecifier("Poses");
|
||||
request.AddSpecifier("Window", index);
|
||||
reply.MakeEmpty();
|
||||
|
||||
status = trackerMessenger.SendMessage(&request, &reply);
|
||||
if (status != B_OK)
|
||||
return _SelectInTracker(tryNumber + 1);
|
||||
|
||||
bool foundRef = false;
|
||||
entry_ref ref;
|
||||
for (int32 m = 0;; m++) {
|
||||
status = reply.FindRef("result", m, &ref);
|
||||
if (status != B_OK)
|
||||
break;
|
||||
if (ref == fOutputEntryRef)
|
||||
foundRef = true;
|
||||
}
|
||||
|
||||
// if entry_ref not found in window, start over
|
||||
if (!foundRef)
|
||||
return _SelectInTracker(tryNumber + 1);
|
||||
|
||||
// select archive file in Tracker window
|
||||
request.MakeEmpty();
|
||||
request.what = B_SET_PROPERTY;
|
||||
request.AddRef("data", &fOutputEntryRef);
|
||||
request.AddSpecifier("Selection");
|
||||
request.AddSpecifier("Poses");
|
||||
request.AddSpecifier("Window", index);
|
||||
reply.MakeEmpty();
|
||||
|
||||
status = trackerMessenger.SendMessage(&request, &reply);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
@ -51,12 +52,15 @@ private:
|
||||
const char* name = NULL,
|
||||
const char* value = NULL);
|
||||
|
||||
status_t _SelectInTracker(int32 tryNumber = 0);
|
||||
|
||||
BMessenger fWindowMessenger;
|
||||
thread_id fZipProcess;
|
||||
int fStdIn;
|
||||
int fStdOut;
|
||||
int fStdErr;
|
||||
FILE* fOutputFile;
|
||||
entry_ref fOutputEntryRef;
|
||||
};
|
||||
|
||||
#endif // _ZIPPER_THREAD_H
|
||||
|
Loading…
Reference in New Issue
Block a user