version 1.0 of Jonas Sundstrom's ZipOMatic app/add-on
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4282 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c0ecc31328
commit
926f5ddfbe
@ -84,4 +84,5 @@ SubInclude OBOS_TOP src add-ons media ;
|
||||
SubInclude OBOS_TOP src add-ons print ;
|
||||
SubInclude OBOS_TOP src add-ons translators ;
|
||||
SubInclude OBOS_TOP src add-ons decorators ;
|
||||
SubInclude OBOS_TOP src add-ons tracker ;
|
||||
|
||||
|
4
src/add-ons/tracker/Jamfile
Normal file
4
src/add-ons/tracker/Jamfile
Normal file
@ -0,0 +1,4 @@
|
||||
SubDir OBOS_TOP src add-ons tracker ;
|
||||
|
||||
SubInclude OBOS_TOP src add-ons tracker zipomatic ;
|
||||
|
386
src/add-ons/tracker/zipomatic/GenericThread.cpp
Normal file
386
src/add-ons/tracker/zipomatic/GenericThread.cpp
Normal file
@ -0,0 +1,386 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
#include <GenericThread.h>
|
||||
|
||||
GenericThread::GenericThread(const char * a_thread_name, int32 a_priority, BMessage * a_message)
|
||||
:
|
||||
m_thread_data_store (a_message),
|
||||
m_thread_id (spawn_thread (private_thread_function, a_thread_name, a_priority, this)),
|
||||
m_execute_unit (create_sem(1, "m_execute_unit")),
|
||||
m_quit_requested (false),
|
||||
m_thread_is_paused (false)
|
||||
{
|
||||
if (m_thread_data_store == NULL)
|
||||
m_thread_data_store = new BMessage();
|
||||
}
|
||||
|
||||
GenericThread::~GenericThread()
|
||||
{
|
||||
kill_thread(m_thread_id);
|
||||
|
||||
delete_sem(m_execute_unit);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::ThreadFunction (void)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = ThreadStartup(); // Subclass and override this function
|
||||
if (status != B_OK)
|
||||
{
|
||||
ThreadStartupFailed (status);
|
||||
return (status);
|
||||
// is this the right thing to do?
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (HasQuitBeenRequested())
|
||||
{
|
||||
status = ThreadShutdown(); // Subclass and override this function
|
||||
if (status != B_OK)
|
||||
{
|
||||
ThreadShutdownFailed (status);
|
||||
return (status);
|
||||
// what do we do?
|
||||
}
|
||||
|
||||
delete this; // destructor
|
||||
}
|
||||
|
||||
BeginUnit();
|
||||
|
||||
status = ExecuteUnit(); // Subclass and override
|
||||
|
||||
if (status != B_OK)
|
||||
ExecuteUnitFailed (status); // Subclass and override
|
||||
|
||||
EndUnit();
|
||||
}
|
||||
|
||||
return (B_OK);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::ThreadStartup (void)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GenericThread::ExecuteUnit (void)
|
||||
{
|
||||
// This function is virtual.
|
||||
|
||||
// You would normally subclass and override this function
|
||||
// as it will provide you with Pause and Quit functionality
|
||||
// thanks to the unit management done by GenericThread::ThreadFunction()
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::ThreadShutdown (void)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ThreadStartupFailed (status_t a_status)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
Quit();
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ExecuteUnitFailed (status_t a_status)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
Quit();
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ThreadShutdownFailed (status_t a_status)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
// (is this good default behaviour?)
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Start (void)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
if (IsPaused())
|
||||
{
|
||||
status = release_sem (m_execute_unit);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
m_thread_is_paused = false;
|
||||
}
|
||||
|
||||
status = resume_thread (m_thread_id);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int32
|
||||
GenericThread::private_thread_function (void * a_simple_thread_ptr)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = ((GenericThread *) a_simple_thread_ptr)-> ThreadFunction();
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
BMessage *
|
||||
GenericThread::GetDataStore (void)
|
||||
{
|
||||
return (m_thread_data_store);
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::SetDataStore (BMessage * a_message)
|
||||
{
|
||||
m_thread_data_store = a_message;
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Pause (bool a_do_block, bigtime_t a_timeout)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
if (a_do_block)
|
||||
status = acquire_sem(m_execute_unit);
|
||||
// thread will wait on semaphore
|
||||
else
|
||||
status = acquire_sem_etc(m_execute_unit, 1, B_RELATIVE_TIMEOUT, a_timeout);
|
||||
// thread will timeout
|
||||
|
||||
if (status == B_OK)
|
||||
{
|
||||
m_thread_is_paused = true;
|
||||
return (B_OK);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::Quit (void)
|
||||
{
|
||||
m_quit_requested = true;
|
||||
}
|
||||
|
||||
bool
|
||||
GenericThread::HasQuitBeenRequested (void)
|
||||
{
|
||||
return (m_quit_requested);
|
||||
}
|
||||
|
||||
bool
|
||||
GenericThread::IsPaused (void)
|
||||
{
|
||||
return (m_thread_is_paused);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Suspend (void)
|
||||
{
|
||||
return (suspend_thread(m_thread_id));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Resume (void)
|
||||
{
|
||||
release_sem(m_execute_unit); // to counteract Pause()
|
||||
m_thread_is_paused = false;
|
||||
|
||||
return (resume_thread(m_thread_id)); // to counteract Suspend()
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Kill (void)
|
||||
{
|
||||
return (kill_thread(m_thread_id));
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ExitWithReturnValue (status_t a_return_value)
|
||||
{
|
||||
exit_thread(a_return_value);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::SetExitCallback (void (*a_callback)(void*), void * a_data)
|
||||
{
|
||||
return (on_exit_thread(a_callback, a_data));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::WaitForThread (status_t * a_exit_value)
|
||||
{
|
||||
return (wait_for_thread(m_thread_id, a_exit_value));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Rename (char * a_name)
|
||||
{
|
||||
return (rename_thread(m_thread_id, a_name));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::SendData (int32 a_code, void * a_buffer, size_t a_buffer_size)
|
||||
{
|
||||
return (send_data(m_thread_id, a_code, a_buffer, a_buffer_size));
|
||||
}
|
||||
|
||||
int32
|
||||
GenericThread::ReceiveData (thread_id * a_sender, void * a_buffer, size_t a_buffer_size)
|
||||
{
|
||||
return (receive_data(a_sender, a_buffer, a_buffer_size));
|
||||
}
|
||||
|
||||
bool
|
||||
GenericThread::HasData (void)
|
||||
{
|
||||
return (has_data(m_thread_id));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::SetPriority (int32 a_new_priority)
|
||||
{
|
||||
return (set_thread_priority(m_thread_id, a_new_priority));
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::Snooze (bigtime_t a_microseconds)
|
||||
{
|
||||
Suspend();
|
||||
snooze(a_microseconds);
|
||||
Resume();
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::SnoozeUntil (bigtime_t a_microseconds, int a_timebase)
|
||||
{
|
||||
Suspend();
|
||||
snooze_until(a_microseconds, a_timebase);
|
||||
Resume();
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::GetInfo (thread_info * a_thread_info)
|
||||
{
|
||||
return (get_thread_info(m_thread_id, a_thread_info));
|
||||
}
|
||||
|
||||
thread_id
|
||||
GenericThread::GetThread (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.thread);
|
||||
}
|
||||
|
||||
team_id
|
||||
GenericThread::GetTeam (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.team);
|
||||
}
|
||||
|
||||
char *
|
||||
GenericThread::GetName (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.name);
|
||||
}
|
||||
|
||||
thread_state
|
||||
GenericThread::GetState (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.state);
|
||||
}
|
||||
|
||||
sem_id
|
||||
GenericThread::GetSemaphore (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.sem);
|
||||
}
|
||||
|
||||
int32
|
||||
GenericThread::GetPriority (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.priority);
|
||||
}
|
||||
|
||||
bigtime_t
|
||||
GenericThread::GetUserTime (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.user_time);
|
||||
}
|
||||
|
||||
bigtime_t
|
||||
GenericThread::GetKernelTime (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.kernel_time);
|
||||
}
|
||||
|
||||
void *
|
||||
GenericThread::GetStackBase (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.stack_base);
|
||||
}
|
||||
|
||||
void *
|
||||
GenericThread::GetStackEnd (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.stack_end);
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::BeginUnit (void)
|
||||
{
|
||||
acquire_sem(m_execute_unit); // thread can not be paused until it releases semaphore
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::EndUnit (void)
|
||||
{
|
||||
release_sem(m_execute_unit); // thread can now be paused
|
||||
}
|
||||
|
83
src/add-ons/tracker/zipomatic/GenericThread.h
Normal file
83
src/add-ons/tracker/zipomatic/GenericThread.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef __GENERIC_THREAD_H__
|
||||
#define __GENERIC_THREAD_H__
|
||||
|
||||
#include <OS.h>
|
||||
#include <Message.h>
|
||||
|
||||
class GenericThread
|
||||
{
|
||||
public:
|
||||
GenericThread (const char * a_thread_name = "generic_thread", int32 a_priority = B_NORMAL_PRIORITY, BMessage * a_message = NULL);
|
||||
virtual ~GenericThread (void);
|
||||
|
||||
BMessage * GetDataStore (void);
|
||||
void SetDataStore (BMessage * a_message);
|
||||
|
||||
status_t Start (void);
|
||||
status_t Pause (bool a_do_block = TRUE, bigtime_t a_timeout = 0);
|
||||
void Quit (void);
|
||||
bool IsPaused (void);
|
||||
bool HasQuitBeenRequested (void);
|
||||
|
||||
status_t Suspend (void);
|
||||
status_t Resume (void);
|
||||
status_t Kill (void);
|
||||
|
||||
void ExitWithReturnValue (status_t a_return_value);
|
||||
status_t SetExitCallback (void (* a_callback)(void *), void * a_data);
|
||||
status_t WaitForThread (status_t * a_exit_value);
|
||||
|
||||
status_t Rename (char * a_name);
|
||||
|
||||
status_t SendData (int32 a_code, void * a_buffer, size_t a_buffer_size);
|
||||
int32 ReceiveData (thread_id * a_sender, void * a_buffer, size_t a_buffer_size);
|
||||
bool HasData (void);
|
||||
|
||||
status_t SetPriority (int32 a_new_priority);
|
||||
|
||||
void Snooze (bigtime_t a_microseconds);
|
||||
void SnoozeUntil (bigtime_t a_microseconds, int a_timebase = B_SYSTEM_TIMEBASE);
|
||||
|
||||
|
||||
status_t GetInfo (thread_info * a_thread_info);
|
||||
thread_id GetThread (void);
|
||||
team_id GetTeam (void);
|
||||
char * GetName (void);
|
||||
thread_state GetState (void);
|
||||
sem_id GetSemaphore (void);
|
||||
int32 GetPriority (void);
|
||||
bigtime_t GetUserTime (void);
|
||||
bigtime_t GetKernelTime (void);
|
||||
void * GetStackBase (void);
|
||||
void * GetStackEnd (void);
|
||||
|
||||
protected:
|
||||
|
||||
virtual status_t ThreadFunction (void);
|
||||
virtual status_t ThreadStartup (void);
|
||||
virtual status_t ExecuteUnit (void);
|
||||
virtual status_t ThreadShutdown (void);
|
||||
|
||||
virtual void ThreadStartupFailed (status_t a_status);
|
||||
virtual void ExecuteUnitFailed (status_t a_status);
|
||||
virtual void ThreadShutdownFailed (status_t a_status);
|
||||
|
||||
void BeginUnit (void); // acquire m_execute_cycle
|
||||
void EndUnit (void); // release m_execute_cycle
|
||||
|
||||
BMessage * m_thread_data_store;
|
||||
|
||||
private:
|
||||
|
||||
static status_t private_thread_function (void * a_simple_thread_ptr);
|
||||
|
||||
thread_id m_thread_id;
|
||||
|
||||
sem_id m_execute_unit; // acq./relase within tread_function.. For Pause()
|
||||
|
||||
bool m_quit_requested;
|
||||
bool m_thread_is_paused;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
19
src/add-ons/tracker/zipomatic/Jamfile
Normal file
19
src/add-ons/tracker/zipomatic/Jamfile
Normal file
@ -0,0 +1,19 @@
|
||||
SubDir OBOS_TOP src add-ons tracker zipomatic ;
|
||||
|
||||
AddResources ZipOMatic-Z :
|
||||
ZipOMatic.rdef ZipOMatic.icons.rdef ZipOMatic.version.rdef
|
||||
;
|
||||
|
||||
App ZipOMatic-Z :
|
||||
GenericThread.cpp
|
||||
ZipOMatic.cpp
|
||||
ZipOMaticActivity.cpp
|
||||
ZipOMaticMisc.cpp
|
||||
ZipOMaticSettings.cpp
|
||||
ZipOMaticView.cpp
|
||||
ZipOMaticWindow.cpp
|
||||
ZipOMaticZipper.cpp
|
||||
;
|
||||
MakeLocate ZipOMatic-Z : [ FDirName $(OBOS_ADDON_DIR) Tracker ] ;
|
||||
|
||||
LinkSharedOSLibs ZipOMatic-Z : be tracker ;
|
187
src/add-ons/tracker/zipomatic/ZipOMatic.cpp
Normal file
187
src/add-ons/tracker/zipomatic/ZipOMatic.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
#include <TrackerAddOn.h>
|
||||
#include <Roster.h>
|
||||
#include <Debug.h>
|
||||
|
||||
#include <ZipOMatic.h>
|
||||
#include <ZipOMaticMisc.h>
|
||||
#include <ZipOMaticWindow.h>
|
||||
|
||||
extern "C" void
|
||||
process_refs(entry_ref dir_ref, BMessage * msg, void *)
|
||||
{
|
||||
msg->AddRef("dir_ref", & dir_ref);
|
||||
|
||||
status_t status = B_OK;
|
||||
type_code ref_type = B_REF_TYPE;
|
||||
int32 ref_count = 0;
|
||||
|
||||
status = msg->GetInfo("refs", & ref_type, & ref_count);
|
||||
if (status != B_OK || ref_count < 1)
|
||||
be_roster->Launch (ZIPOMATIC_APP_SIG);
|
||||
else
|
||||
be_roster->Launch (ZIPOMATIC_APP_SIG, msg );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ZipOMatic app;
|
||||
app.Run();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ZipOMatic::ZipOMatic (void)
|
||||
: BApplication (ZIPOMATIC_APP_SIG),
|
||||
m_got_refs (false)
|
||||
{
|
||||
PRINT(("ZipOMatic::ZipOMatic()\n"));
|
||||
|
||||
// void
|
||||
}
|
||||
|
||||
ZipOMatic::~ZipOMatic (void)
|
||||
{
|
||||
PRINT(("ZipOMatic::~ZipOMatic()\n"));
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
ZipOMatic::RefsReceived (BMessage * a_message)
|
||||
{
|
||||
PRINT(("ZipOMatic::RefsReceived()\n"));
|
||||
|
||||
if (IsLaunching())
|
||||
m_got_refs = true;
|
||||
|
||||
BMessage * msg = new BMessage (* a_message);
|
||||
|
||||
UseExistingOrCreateNewWindow(msg);
|
||||
}
|
||||
|
||||
void
|
||||
ZipOMatic::ReadyToRun (void)
|
||||
{
|
||||
PRINT(("ZipOMatic::ReadyToRun()\n"));
|
||||
|
||||
if (m_got_refs)
|
||||
{
|
||||
// nothing - wait on window(s) to finish
|
||||
}
|
||||
else
|
||||
UseExistingOrCreateNewWindow();
|
||||
}
|
||||
|
||||
void
|
||||
ZipOMatic::MessageReceived (BMessage * a_message)
|
||||
{
|
||||
PRINT(("ZipOMatic::MessageReceived()\n"));
|
||||
|
||||
switch(a_message->what)
|
||||
{
|
||||
case ZIPPO_WINDOW_QUIT:
|
||||
|
||||
snooze (200000);
|
||||
if (CountWindows() == 0)
|
||||
Quit();
|
||||
break;
|
||||
|
||||
case B_SILENT_RELAUNCH:
|
||||
|
||||
SilentRelaunch();
|
||||
break;
|
||||
|
||||
default: BApplication::MessageReceived(a_message); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
ZipOMatic::QuitRequested (void)
|
||||
{
|
||||
// intelligent (?) closing of the windows
|
||||
//
|
||||
// overriding BApplication::QuitRequested();
|
||||
|
||||
if (CountWindows() <= 0)
|
||||
return true;
|
||||
|
||||
BList window_list (5);
|
||||
int32 window_count = 0;
|
||||
BWindow * window;
|
||||
|
||||
// build list of windows
|
||||
while (1)
|
||||
{
|
||||
window = WindowAt(window_count++);
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
window_list.AddItem(window);
|
||||
}
|
||||
|
||||
// ask windows to quit
|
||||
while (1)
|
||||
{
|
||||
window = (BWindow *) window_list.RemoveItem(int32(0));
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
if (window->Lock())
|
||||
{
|
||||
window->PostMessage(B_QUIT_REQUESTED);
|
||||
window->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
PRINT(("CountWindows(): %ld\n", CountWindows()));
|
||||
|
||||
if (CountWindows() <= 0)
|
||||
return true;
|
||||
|
||||
return false; // default: stay alive
|
||||
}
|
||||
|
||||
void
|
||||
ZipOMatic::SilentRelaunch (void)
|
||||
{
|
||||
UseExistingOrCreateNewWindow();
|
||||
}
|
||||
|
||||
void
|
||||
ZipOMatic::UseExistingOrCreateNewWindow (BMessage * a_message)
|
||||
{
|
||||
int32 window_count = 0;
|
||||
ZippoWindow * window;
|
||||
bool found_non_busy_window = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
window = dynamic_cast<ZippoWindow *>(WindowAt(window_count++));
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
if (window->Lock())
|
||||
{
|
||||
if (! window->IsZipping())
|
||||
{
|
||||
found_non_busy_window = true;
|
||||
if (a_message != NULL)
|
||||
window->PostMessage(a_message);
|
||||
window->Activate();
|
||||
window->Unlock();
|
||||
break;
|
||||
}
|
||||
window->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_non_busy_window)
|
||||
{
|
||||
ZippoWindow * m_window = new ZippoWindow(a_message);
|
||||
m_window->Show();
|
||||
}
|
||||
}
|
28
src/add-ons/tracker/zipomatic/ZipOMatic.h
Normal file
28
src/add-ons/tracker/zipomatic/ZipOMatic.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _ZIPOMATIC_H_
|
||||
#define _ZIPOMATIC_H_
|
||||
|
||||
#include <Application.h>
|
||||
#include <Message.h>
|
||||
|
||||
class ZipOMatic : public BApplication
|
||||
{
|
||||
public:
|
||||
ZipOMatic (void);
|
||||
~ZipOMatic (void);
|
||||
|
||||
virtual void ReadyToRun (void);
|
||||
virtual void RefsReceived (BMessage * a_message);
|
||||
virtual void MessageReceived (BMessage * a_message);
|
||||
virtual bool QuitRequested (void);
|
||||
|
||||
void SilentRelaunch (void);
|
||||
void UseExistingOrCreateNewWindow (BMessage * a_message = NULL);
|
||||
|
||||
private:
|
||||
|
||||
bool m_got_refs;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _ZIPOMATIC_H_
|
59
src/add-ons/tracker/zipomatic/ZipOMatic.icons.rdef
Normal file
59
src/add-ons/tracker/zipomatic/ZipOMatic.icons.rdef
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
** ZipOMatic.icons.rdef
|
||||
**
|
||||
*/
|
||||
|
||||
resource large_icon array {
|
||||
$"FFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFF00FAFAFAFA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFF00FAFAFAFAFAFA5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFF00FAFAFAFAFA5D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFF003FF9F9FA5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFF007D3FF9F9F95D5D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFF007D7D3FF9F9F95D5D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FF003F3F7D3FF9F9F95D5D5D00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFF00F93F3FF9F9F95D5D5D0000D9D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFF00F9F93FF9F9F95D5D7D7D7D0000D9D90000FFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFF00F9F9F9F9F93F3F7D7D7D00D9D9D9D9D90000FFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFF00F9F9F9F9F9F93F7D00D9D9D9D9D9D900D90000FFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFF00F9F9F9F9F9F90000D9D900D9D9D900D9D9D9D90000FFFFFFFFFFFF"
|
||||
$"FFFFFFFFFF00F9F9F9F900D9D9D9D900D9D900D9D9D9D9D9D9D90000FFFFFFFF"
|
||||
$"FFFFFFFF00D900F90000000000000000D900D9D9D9D9D9D9D9D9D9D900FFFFFF"
|
||||
$"FFFFFF00D9D9D900D9000000D9D9000000D9D9D9D9D9D9D9D9D9D9D9D900FFFF"
|
||||
$"FFFF00D9D9D9D9D9D900D9D90000D900000000000000D9D9D9D9D9D9D9D900FF"
|
||||
$"FF00D9D9D9D9D9D9D9D9000000D9000000D9D9D9D9D900D9D9D9D9D9D98300FF"
|
||||
$"FF00D9D9D9D9D9D9D9D9D9D9D900D9D90000D9D90000D9D9D9D9D9D9838300FF"
|
||||
$"00D9D9D9D9D9D9D9D9D9D9D900D9D900D900000000D9D9D9D9D9D983838300FF"
|
||||
$"00D9D9D9D9D9D9D9D9D9D900D9D9D900D9D9D9D9D90000D9D9D98383838300FF"
|
||||
$"00D9D9D9D9D9D9D9D9D900D9D9D9D9D9D9D9D9D9D9D9D900008383838300FFFF"
|
||||
$"FF00D9D9D9D9D9D9D900D9D9D9D9D9D9D9D9D9D9D9D9D9D90083838300FFFFFF"
|
||||
$"FFFF0000D9D9D9D9D901D9D9D9D9D9D9D9D9D9D9D9D9D98300838300FFFFFFFF"
|
||||
$"FFFFFFFF0000D9D9D901D9D9D9D9D9D9D9D9D9D9D9D98383008300FFFFFFFFFF"
|
||||
$"FFFFFFFFFFFF0000D900D9D9D9D9D9D9D9D9D9D9D98383830000FFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFF0000D9D9D9D9D9D9D9D9D9D98383838300FFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFF0000D9D9D9D9D9D9D98383838301FFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFF0000D9D9D9D98383838301FFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000D9D983830100FFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
};
|
||||
|
||||
resource mini_icon array {
|
||||
$"FFFFFFFF000000FFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFF00FAFA5D00FFFFFFFFFFFFFFFF"
|
||||
$"FFFF003F3F3F5D00FFFFFFFFFFFFFFFF"
|
||||
$"FFFF003FF9F95D0000FFFFFFFFFFFFFF"
|
||||
$"FF00003FF9F95D00D90000FFFFFFFFFF"
|
||||
$"007D003FF9F95D7D00D9000000FFFFFF"
|
||||
$"3F00F9F9F9F93F008300D9D9D90000FF"
|
||||
$"3F0000F9F9F90000000000D9D9D98300"
|
||||
$"00D9D900F900000083D9D900D93F8300"
|
||||
$"00D93FD900830000000000D93F838300"
|
||||
$"00D9D9D9D900D900D9D9D901008300FF"
|
||||
$"0000D9D9003FD900D9D93F830000FFFF"
|
||||
$"FFFF000000D9D93FD93F838300FFFFFF"
|
||||
$"FFFFFFFF0000D9D9D9838301FFFFFFFF"
|
||||
$"FFFFFFFFFFFF0000D98301FFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF"
|
||||
};
|
||||
|
12
src/add-ons/tracker/zipomatic/ZipOMatic.rdef
Normal file
12
src/add-ons/tracker/zipomatic/ZipOMatic.rdef
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
** ZipOMatic.rdef
|
||||
**
|
||||
*/
|
||||
|
||||
resource app_signature "application/x-vnd.obos.zip-o-matic";
|
||||
|
||||
resource app_flags 0x00000000;
|
||||
|
||||
resource file_types message {
|
||||
"types" = "application/octet-stream"
|
||||
};
|
20
src/add-ons/tracker/zipomatic/ZipOMatic.version.rdef
Normal file
20
src/add-ons/tracker/zipomatic/ZipOMatic.version.rdef
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
** ZipOMatic.version.rdef
|
||||
**
|
||||
*/
|
||||
|
||||
resource app_version {
|
||||
|
||||
major = 1,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
|
||||
/* 0 = development 1 = alpha 2 = beta
|
||||
3 = gamma 4 = golden master 5 = final */
|
||||
variety = 0,
|
||||
|
||||
internal = 1,
|
||||
|
||||
short_info = "R1.0.0d1",
|
||||
long_info = "OpenBeOS 1.0.0d1 ©2003 OpenBeOS Project"
|
||||
};
|
232
src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp
Normal file
232
src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
#include <ZipOMaticActivity.h>
|
||||
|
||||
Activity::Activity (BRect a_rect, const char * a_name, uint32 a_resizing_mode, uint32 a_flags)
|
||||
: BBox (a_rect, a_name, a_resizing_mode, a_flags),
|
||||
m_is_running (false),
|
||||
m_barberpole_bitmap (NULL)
|
||||
{
|
||||
m_pattern.data[0] = 0x0f;
|
||||
m_pattern.data[1] = 0x1e;
|
||||
m_pattern.data[2] = 0x3c;
|
||||
m_pattern.data[3] = 0x78;
|
||||
m_pattern.data[4] = 0xf0;
|
||||
m_pattern.data[5] = 0xe1;
|
||||
m_pattern.data[6] = 0xc3;
|
||||
m_pattern.data[7] = 0x87;
|
||||
|
||||
CreateBitmap();
|
||||
};
|
||||
|
||||
Activity::~Activity()
|
||||
{
|
||||
// subviews are deleted by superclass
|
||||
|
||||
delete m_barberpole_bitmap;
|
||||
}
|
||||
|
||||
void
|
||||
Activity::Start()
|
||||
{
|
||||
m_is_running = true;
|
||||
Window()->SetPulseRate(100000);
|
||||
SetFlags(Flags() | B_PULSE_NEEDED);
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void
|
||||
Activity::Pause()
|
||||
{
|
||||
Window()->SetPulseRate(500000);
|
||||
SetFlags(Flags() & (~ B_PULSE_NEEDED));
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void
|
||||
Activity::Stop()
|
||||
{
|
||||
m_is_running = false;
|
||||
Window()->SetPulseRate(500000);
|
||||
SetFlags(Flags() & (~ B_PULSE_NEEDED));
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
bool
|
||||
Activity::IsRunning()
|
||||
{
|
||||
return m_is_running;
|
||||
}
|
||||
|
||||
void
|
||||
Activity::Pulse()
|
||||
{
|
||||
uchar tmp = m_pattern.data[7];
|
||||
|
||||
for (int j = 7; j > 0; --j)
|
||||
{
|
||||
m_pattern.data[j] = m_pattern.data[j-1];
|
||||
}
|
||||
|
||||
m_pattern.data[0] = tmp;
|
||||
|
||||
DrawIntoBitmap();
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void
|
||||
Activity::Draw(BRect a_rect)
|
||||
{
|
||||
if (IsRunning())
|
||||
{
|
||||
// draw BBox outline
|
||||
BBox::Draw(a_rect);
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
DrawBitmap(m_barberpole_bitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
BBox::Draw(a_rect);
|
||||
|
||||
float string_width = StringWidth("Drop files to zip.");
|
||||
float view_width = Bounds().Width();
|
||||
|
||||
MovePenTo ((view_width/2)-(string_width/2),12);
|
||||
DrawString("Drop files to zip.");
|
||||
}
|
||||
}
|
||||
|
||||
void Activity::DrawIntoBitmap (void)
|
||||
{
|
||||
if (m_barberpole_bitmap->Lock())
|
||||
{
|
||||
BRect a_rect = m_barberpole_bitmap->Bounds();
|
||||
|
||||
m_barberpole_bitmap_view->SetDrawingMode(B_OP_COPY);
|
||||
|
||||
rgb_color color;
|
||||
color.red = 0;
|
||||
color.green = 0;
|
||||
color.blue = 200;
|
||||
color.alpha = 255;
|
||||
m_barberpole_bitmap_view->SetHighColor(color);
|
||||
|
||||
// draw the pole
|
||||
a_rect.InsetBy(2,2);
|
||||
m_barberpole_bitmap_view->FillRect(a_rect, m_pattern);
|
||||
|
||||
// draw frame
|
||||
|
||||
// left
|
||||
color.red = 150;
|
||||
color.green = 150;
|
||||
color.blue = 150;
|
||||
m_barberpole_bitmap_view->SetHighColor(color);
|
||||
BPoint point_a = m_barberpole_bitmap->Bounds().LeftTop();
|
||||
BPoint point_b = m_barberpole_bitmap->Bounds().LeftBottom();
|
||||
point_b.y -= 1;
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
point_a.x += 1;
|
||||
point_b.x += 1;
|
||||
point_b.y -= 1;
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
|
||||
// top
|
||||
m_barberpole_bitmap_view->SetDrawingMode(B_OP_OVER);
|
||||
m_barberpole_bitmap_view->SetHighColor(color);
|
||||
point_a = m_barberpole_bitmap->Bounds().LeftTop();
|
||||
point_b = m_barberpole_bitmap->Bounds().RightTop();
|
||||
point_b.x -= 1;
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
point_a.y += 1;
|
||||
point_b.y += 1;
|
||||
point_b.x -= 1;
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
|
||||
// right
|
||||
color.red = 255;
|
||||
color.green = 255;
|
||||
color.blue = 255;
|
||||
m_barberpole_bitmap_view->SetHighColor(color);
|
||||
point_a = m_barberpole_bitmap->Bounds().RightTop();
|
||||
point_b = m_barberpole_bitmap->Bounds().RightBottom();
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
point_a.y += 1;
|
||||
point_a.x -= 1;
|
||||
point_b.x -= 1;
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
|
||||
// bottom
|
||||
m_barberpole_bitmap_view->SetHighColor(color);
|
||||
point_a = m_barberpole_bitmap->Bounds().LeftBottom();
|
||||
point_b = m_barberpole_bitmap->Bounds().RightBottom();
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
point_a.x += 1;
|
||||
point_a.y -= 1;
|
||||
point_b.y -= 1;
|
||||
m_barberpole_bitmap_view->StrokeLine(point_a, point_b);
|
||||
|
||||
// some blending
|
||||
color.red = 150;
|
||||
color.green = 150;
|
||||
color.blue = 150;
|
||||
m_barberpole_bitmap_view->SetHighColor(color);
|
||||
m_barberpole_bitmap_view->SetDrawingMode(B_OP_SUBTRACT);
|
||||
m_barberpole_bitmap_view->StrokeRect(a_rect);
|
||||
|
||||
a_rect.InsetBy(1,1);
|
||||
LightenBitmapHighColor(& color);
|
||||
m_barberpole_bitmap_view->StrokeRect(a_rect);
|
||||
|
||||
a_rect.InsetBy(1,1);
|
||||
LightenBitmapHighColor(& color);
|
||||
m_barberpole_bitmap_view->StrokeRect(a_rect);
|
||||
|
||||
a_rect.InsetBy(1,1);
|
||||
LightenBitmapHighColor(& color);
|
||||
m_barberpole_bitmap_view->StrokeRect(a_rect);
|
||||
|
||||
a_rect.InsetBy(1,1);
|
||||
LightenBitmapHighColor(& color);
|
||||
m_barberpole_bitmap_view->StrokeRect(a_rect);
|
||||
|
||||
m_barberpole_bitmap_view->Flush();
|
||||
}
|
||||
|
||||
m_barberpole_bitmap->Unlock();
|
||||
}
|
||||
|
||||
void Activity::LightenBitmapHighColor (rgb_color * a_color)
|
||||
{
|
||||
a_color->red -= 30;
|
||||
a_color->green -= 30;
|
||||
a_color->blue -= 30;
|
||||
|
||||
m_barberpole_bitmap_view->SetHighColor(* a_color);
|
||||
}
|
||||
|
||||
void Activity::CreateBitmap (void)
|
||||
{
|
||||
BRect barberpole_rect = Bounds();
|
||||
m_barberpole_bitmap = new BBitmap(barberpole_rect, B_CMAP8, true);
|
||||
m_barberpole_bitmap_view = new BView(Bounds(), "buffer", B_FOLLOW_NONE, 0);
|
||||
m_barberpole_bitmap->AddChild(m_barberpole_bitmap_view);
|
||||
}
|
||||
|
||||
void Activity::FrameMoved (BPoint a_point)
|
||||
{
|
||||
delete m_barberpole_bitmap;
|
||||
CreateBitmap();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void Activity::FrameResized (float a_width, float a_height)
|
||||
{
|
||||
delete m_barberpole_bitmap;
|
||||
CreateBitmap();
|
||||
Invalidate();
|
||||
}
|
42
src/add-ons/tracker/zipomatic/ZipOMaticActivity.h
Normal file
42
src/add-ons/tracker/zipomatic/ZipOMaticActivity.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef _ACTIVITY_H_
|
||||
#define _ACTIVITY_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Window.h>
|
||||
#include <View.h>
|
||||
#include <Box.h>
|
||||
#include <Bitmap.h>
|
||||
|
||||
class Activity : public BBox
|
||||
{
|
||||
public:
|
||||
Activity (BRect a_rect, const char * a_name, uint32 a_resizing_mode,
|
||||
uint32 a_flags);
|
||||
~Activity ();
|
||||
|
||||
void Start ();
|
||||
void Pause ();
|
||||
void Stop ();
|
||||
bool IsRunning ();
|
||||
virtual void Pulse ();
|
||||
virtual void Draw (BRect a_draw);
|
||||
virtual void FrameMoved (BPoint a_point);
|
||||
virtual void FrameResized (float a_width, float a_height);
|
||||
|
||||
protected:
|
||||
void CreateBitmap (void);
|
||||
void LightenBitmapHighColor (rgb_color * a_color);
|
||||
void DrawIntoBitmap (void);
|
||||
|
||||
bool m_is_running;
|
||||
pattern m_pattern;
|
||||
|
||||
BBitmap * m_barberpole_bitmap;
|
||||
BView * m_barberpole_bitmap_view;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
47
src/add-ons/tracker/zipomatic/ZipOMaticMisc.cpp
Normal file
47
src/add-ons/tracker/zipomatic/ZipOMaticMisc.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
#include <ZipOMaticMisc.h>
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
status_t
|
||||
find_and_create_directory (directory_which a_which, BVolume * a_volume, const char * a_relative_path, BPath * a_full_path)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
BPath path;
|
||||
mode_t mask = 0;
|
||||
|
||||
status = find_directory (a_which, & path, true, a_volume); // create = true
|
||||
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (a_relative_path != NULL)
|
||||
{
|
||||
path.Append(a_relative_path);
|
||||
|
||||
mask = umask (0);
|
||||
umask (mask);
|
||||
|
||||
status = create_directory (path.Path(), mask);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (a_full_path != NULL)
|
||||
{
|
||||
status = a_full_path->SetTo(path.Path());
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
error_message (const char * a_text, int32 a_status)
|
||||
{
|
||||
PRINT(("%s: %s\n", a_text, strerror(a_status)));
|
||||
}
|
||||
|
24
src/add-ons/tracker/zipomatic/ZipOMaticMisc.h
Normal file
24
src/add-ons/tracker/zipomatic/ZipOMaticMisc.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __ZIPOMATIC_MISC__
|
||||
#define __ZIPOMATIC_MISC__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <Volume.h>
|
||||
#include <Path.h>
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
|
||||
#define ZIPOMATIC_APP_SIG "application/x-vnd.obos.zip-o-matic"
|
||||
#define ZIPOMATIC_APP_NAME "ZipOMatic"
|
||||
|
||||
#define ZIPPO_WINDOW_QUIT 'winq'
|
||||
|
||||
status_t find_and_create_directory (directory_which a_which, BVolume * a_volume = NULL, const char * a_relative_path = NULL, BPath * a_full_path = NULL);
|
||||
|
||||
void error_message (const char * a_text, int32 a_status);
|
||||
|
||||
#endif // __ZIPOMATIC_MISC__
|
||||
|
140
src/add-ons/tracker/zipomatic/ZipOMaticSettings.cpp
Normal file
140
src/add-ons/tracker/zipomatic/ZipOMaticSettings.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
//
|
||||
// TODO: proper locking <<---------
|
||||
//
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include <VolumeRoster.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Directory.h>
|
||||
#include <Path.h>
|
||||
#include <File.h>
|
||||
|
||||
#include <ZipOMaticMisc.h>
|
||||
#include <ZipOMaticSettings.h>
|
||||
|
||||
ZippoSettings::ZippoSettings()
|
||||
: BMessage (),
|
||||
m_volume (),
|
||||
m_base_dir (B_USER_SETTINGS_DIRECTORY),
|
||||
m_relative_path (),
|
||||
m_settings_filename ()
|
||||
{
|
||||
PRINT(("ZippoSettings()\n"));
|
||||
}
|
||||
|
||||
ZippoSettings::ZippoSettings(BMessage a_message)
|
||||
: BMessage (a_message),
|
||||
m_volume (),
|
||||
m_base_dir (B_USER_SETTINGS_DIRECTORY),
|
||||
m_relative_path (),
|
||||
m_settings_filename ()
|
||||
{
|
||||
PRINT(("ZippoSettings(a_message)\n"));
|
||||
}
|
||||
|
||||
ZippoSettings::~ZippoSettings()
|
||||
{
|
||||
m_volume.Unset();
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoSettings::SetTo (const char * a_settings_filename,
|
||||
BVolume * a_volume,
|
||||
directory_which a_base_dir,
|
||||
const char * a_relative_path)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
// copy to members
|
||||
m_base_dir = a_base_dir;
|
||||
m_relative_path = a_relative_path;
|
||||
m_settings_filename = a_settings_filename;
|
||||
|
||||
// sanity check
|
||||
if (a_volume == NULL)
|
||||
{
|
||||
BVolumeRoster volume_roster;
|
||||
volume_roster.GetBootVolume(& m_volume);
|
||||
}
|
||||
else
|
||||
m_volume = *(a_volume);
|
||||
|
||||
status = m_volume.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// InitCheck
|
||||
return InitCheck();
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoSettings::InitCheck (void)
|
||||
{
|
||||
BFile settings_file;
|
||||
|
||||
return GetSettingsFile (& settings_file, B_READ_ONLY | B_CREATE_FILE);
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoSettings::GetSettingsFile (BFile * a_settings_file, uint32 a_openmode)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
BPath settings_path;
|
||||
|
||||
status = find_and_create_directory(m_base_dir, & m_volume, m_relative_path.String(), & settings_path);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = settings_path.Append (m_settings_filename.String());
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = a_settings_file->SetTo (settings_path.Path(), a_openmode);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoSettings::ReadSettings (void)
|
||||
{
|
||||
PRINT(("ZippoSettings::ReadSettings()\n"));
|
||||
|
||||
status_t status = B_OK;
|
||||
BFile settings_file;
|
||||
|
||||
status = GetSettingsFile (& settings_file, B_READ_ONLY);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = Unflatten(& settings_file);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoSettings::WriteSettings (void)
|
||||
{
|
||||
PRINT(("ZippoSettings::WriteSettings()\n"));
|
||||
|
||||
status_t status = B_OK;
|
||||
BFile settings_file;
|
||||
|
||||
status = GetSettingsFile (& settings_file, B_WRITE_ONLY | B_ERASE_FILE);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = Flatten(& settings_file);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
36
src/add-ons/tracker/zipomatic/ZipOMaticSettings.h
Normal file
36
src/add-ons/tracker/zipomatic/ZipOMaticSettings.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef __ZIPPO_SETTINGS_H__
|
||||
#define __ZIPPO_SETTINGS_H__
|
||||
|
||||
#include <Message.h>
|
||||
#include <Volume.h>
|
||||
#include <String.h>
|
||||
|
||||
class ZippoSettings : public BMessage
|
||||
{
|
||||
public:
|
||||
ZippoSettings ();
|
||||
ZippoSettings (BMessage a_message);
|
||||
~ZippoSettings ();
|
||||
|
||||
status_t SetTo (const char * a_settings_filename,
|
||||
BVolume * a_volume = NULL,
|
||||
directory_which a_base_dir = B_USER_SETTINGS_DIRECTORY,
|
||||
const char * a_relative_path = NULL);
|
||||
|
||||
status_t InitCheck (void);
|
||||
|
||||
status_t ReadSettings ();
|
||||
status_t WriteSettings ();
|
||||
|
||||
private:
|
||||
|
||||
status_t GetSettingsFile (BFile * a_settings_file, uint32 a_openmode);
|
||||
|
||||
BVolume m_volume;
|
||||
directory_which m_base_dir;
|
||||
BString m_relative_path;
|
||||
BString m_settings_filename;
|
||||
|
||||
};
|
||||
|
||||
#endif // __ZIPPO_SETTINGS_H__
|
87
src/add-ons/tracker/zipomatic/ZipOMaticView.cpp
Normal file
87
src/add-ons/tracker/zipomatic/ZipOMaticView.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
#include <ZipOMaticActivity.h>
|
||||
#include <ZipOMaticView.h>
|
||||
|
||||
ZippoView::ZippoView (BRect a_rect)
|
||||
: BBox (a_rect, "zipomatic_view", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
|
||||
B_PLAIN_BORDER),
|
||||
m_stop_button (NULL)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
// "Stop" button
|
||||
BRect button_rect (a_rect.right-82, a_rect.bottom-32, a_rect.right-12, a_rect.bottom-12);
|
||||
m_stop_button = new BButton(button_rect,"stop_button","Stop", new BMessage(B_QUIT_REQUESTED), B_FOLLOW_RIGHT);
|
||||
m_stop_button->SetEnabled(false);
|
||||
AddChild(m_stop_button);
|
||||
|
||||
// activity view
|
||||
BRect activity_rect (a_rect.left+14, a_rect.top+15, a_rect.right-15, a_rect.top+31);
|
||||
m_activity_view = new Activity (activity_rect, "activity_view", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS);
|
||||
AddChild(m_activity_view);
|
||||
|
||||
// text views
|
||||
BRect archive_rect (a_rect.left+14, a_rect.top+30, a_rect.right-15, a_rect.top+47);
|
||||
m_archive_name_view = new BStringView (archive_rect, "archive_text", " ", B_FOLLOW_LEFT_RIGHT);
|
||||
AddChild (m_archive_name_view);
|
||||
|
||||
BRect ouput_rect (a_rect.left+14, a_rect.top+47, a_rect.right-15, a_rect.top+66);
|
||||
m_zip_output_view = new BStringView (ouput_rect, "output_text", " ", B_FOLLOW_LEFT_RIGHT);
|
||||
AddChild (m_zip_output_view);
|
||||
|
||||
}
|
||||
|
||||
void ZippoView::Draw (BRect a_update_rect)
|
||||
{
|
||||
BBox::Draw(a_update_rect);
|
||||
// fBox->DrawBitmap(fIconBitmap,BPoint(178,26));
|
||||
|
||||
const rgb_color grey_accent = {128,128,128,255};
|
||||
const rgb_color darker_grey = {108,108,108,255};
|
||||
const rgb_color plain_white = {255,255,255,255};
|
||||
const rgb_color deep_black = {255,255,255,255};
|
||||
|
||||
// "preflet" bottom, right grey accent lines
|
||||
|
||||
SetHighColor(grey_accent);
|
||||
|
||||
StrokeLine (BPoint(Bounds().right, Bounds().top),
|
||||
BPoint(Bounds().right, Bounds().bottom));
|
||||
|
||||
StrokeLine (BPoint(Bounds().left, Bounds().bottom),
|
||||
BPoint(Bounds().right, Bounds().bottom));
|
||||
|
||||
// divider
|
||||
SetHighColor(darker_grey);
|
||||
StrokeLine (BPoint(Bounds().left+15, Bounds().top+71),
|
||||
BPoint(Bounds().right-16, Bounds().top+71));
|
||||
|
||||
SetHighColor(plain_white);
|
||||
StrokeLine (BPoint(Bounds().left+15, Bounds().top+72),
|
||||
BPoint(Bounds().right-16, Bounds().top+72));
|
||||
|
||||
// text
|
||||
SetHighColor(deep_black);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ZippoView::AllAttached (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZippoView::FrameMoved (BPoint a_point)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ZippoView::FrameResized (float a_width, float a_height)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
31
src/add-ons/tracker/zipomatic/ZipOMaticView.h
Normal file
31
src/add-ons/tracker/zipomatic/ZipOMaticView.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __ZIPPO_VIEW_H__
|
||||
#define __ZIPPO_VIEW_H__
|
||||
|
||||
#include <Box.h>
|
||||
#include <Button.h>
|
||||
#include <StringView.h>
|
||||
|
||||
class Activity;
|
||||
|
||||
class ZippoView : public BBox
|
||||
{
|
||||
public:
|
||||
ZippoView (BRect frame);
|
||||
|
||||
virtual void Draw (BRect frame);
|
||||
virtual void AllAttached (void);
|
||||
virtual void FrameMoved (BPoint a_point);
|
||||
virtual void FrameResized (float a_width, float a_height);
|
||||
|
||||
BButton * m_stop_button;
|
||||
Activity * m_activity_view;
|
||||
|
||||
BStringView * m_archive_name_view;
|
||||
BStringView * m_zip_output_view;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // __ZIPPO_VIEW_H__
|
328
src/add-ons/tracker/zipomatic/ZipOMaticWindow.cpp
Normal file
328
src/add-ons/tracker/zipomatic/ZipOMaticWindow.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Roster.h>
|
||||
#include <InterfaceKit.h>
|
||||
#include <String.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Directory.h>
|
||||
#include <Path.h>
|
||||
#include <File.h>
|
||||
|
||||
#include <ZipOMatic.h>
|
||||
#include <ZipOMaticActivity.h>
|
||||
#include <ZipOMaticMisc.h>
|
||||
#include <ZipOMaticView.h>
|
||||
#include <ZipOMaticWindow.h>
|
||||
#include <ZipOMaticZipper.h>
|
||||
|
||||
ZippoWindow::ZippoWindow(BMessage * a_message)
|
||||
: BWindow(BRect(200,200,430,310), "Zip-O-Matic", B_TITLED_WINDOW, B_NOT_V_RESIZABLE), // | B_NOT_ZOOMABLE),
|
||||
m_zippo_settings (),
|
||||
m_zipper_thread (NULL),
|
||||
m_got_refs_at_window_startup (false),
|
||||
m_zipping_was_stopped (false),
|
||||
m_alert_invoker_message (new BMessage ('alrt')),
|
||||
m_alert_window_invoker (new BInvoker (m_alert_invoker_message, NULL, this))
|
||||
{
|
||||
PRINT(("ZippoWindow()\n"));
|
||||
|
||||
// Settings
|
||||
status_t status = B_OK;
|
||||
|
||||
status = m_zippo_settings.SetTo("ZipOMatic.msg");
|
||||
if (status != B_OK)
|
||||
error_message("ZippoWindow() - m_zippo_settings.SetTo()", status);
|
||||
|
||||
status = m_zippo_settings.InitCheck();
|
||||
if (status != B_OK)
|
||||
error_message("ZippoWindow() - m_zippo_settings.InitCheck()", status);
|
||||
|
||||
// Interface
|
||||
zippoview = new ZippoView(Bounds());
|
||||
|
||||
AddChild (zippoview);
|
||||
|
||||
SetSizeLimits(Bounds().Width(), 15000, Bounds().Height(), Bounds().Height());
|
||||
|
||||
// Settings, (on-screen location of window)
|
||||
ReadSettings();
|
||||
|
||||
// Start zipper thread
|
||||
if (a_message != NULL)
|
||||
{
|
||||
m_got_refs_at_window_startup = true;
|
||||
StartZipping (a_message);
|
||||
}
|
||||
}
|
||||
|
||||
ZippoWindow::~ZippoWindow()
|
||||
{
|
||||
PRINT(("ZippoWindow::~ZippoWindow()\n"));
|
||||
|
||||
//delete m_alert_invoker_message;
|
||||
delete m_alert_window_invoker;
|
||||
|
||||
// anything left to clean up?
|
||||
}
|
||||
|
||||
void
|
||||
ZippoWindow::MessageReceived (BMessage * a_message)
|
||||
{
|
||||
switch(a_message->what)
|
||||
{
|
||||
|
||||
case B_REFS_RECEIVED:
|
||||
StartZipping (a_message);
|
||||
break;
|
||||
|
||||
case B_SIMPLE_DATA:
|
||||
if (IsZipping())
|
||||
{
|
||||
a_message->what = B_REFS_RECEIVED;
|
||||
be_app_messenger.SendMessage(a_message);
|
||||
}
|
||||
else
|
||||
StartZipping (a_message);
|
||||
break;
|
||||
|
||||
case 'exit': // thread has finished (finished, quit, killed, we don't know)
|
||||
// reset window state
|
||||
{
|
||||
m_zipper_thread = NULL;
|
||||
zippoview->m_activity_view->Stop();
|
||||
zippoview->m_archive_name_view->SetText(" ");
|
||||
if (m_zipping_was_stopped)
|
||||
zippoview->m_zip_output_view->SetText("Stopped");
|
||||
else
|
||||
zippoview->m_zip_output_view->SetText("Archive created OK");
|
||||
|
||||
CloseWindowOrKeepOpen();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'exrr': // thread has finished
|
||||
// reset window state
|
||||
|
||||
m_zipper_thread = NULL;
|
||||
zippoview->m_activity_view->Stop();
|
||||
zippoview->m_archive_name_view->SetText("");
|
||||
zippoview->m_zip_output_view->SetText("Error creating archive");
|
||||
//CloseWindowOrKeepOpen();
|
||||
break;
|
||||
|
||||
case 'strt':
|
||||
{
|
||||
BString archive_filename;
|
||||
if (a_message->FindString("archive_filename", & archive_filename) == B_OK)
|
||||
zippoview->m_archive_name_view->SetText(archive_filename.String());
|
||||
break;
|
||||
}
|
||||
|
||||
case 'outp':
|
||||
{
|
||||
BString zip_output;
|
||||
if (a_message->FindString("zip_output", & zip_output) == B_OK)
|
||||
zippoview->m_zip_output_view->SetText(zip_output.String());
|
||||
break;
|
||||
}
|
||||
|
||||
case 'alrt':
|
||||
{
|
||||
int32 which_button = -1;
|
||||
if (a_message->FindInt32("which", & which_button) == B_OK)
|
||||
if (which_button == 0)
|
||||
StopZipping();
|
||||
else
|
||||
{
|
||||
if (m_zipper_thread != NULL)
|
||||
m_zipper_thread->ResumeExternalZip();
|
||||
|
||||
zippoview->m_activity_view->Start();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: BWindow::MessageReceived(a_message); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ZippoWindow::QuitRequested (void)
|
||||
{
|
||||
PRINT(("ZippoWindow::QuitRequested()\n"));
|
||||
|
||||
if (m_zipper_thread == NULL)
|
||||
{
|
||||
WriteSettings();
|
||||
be_app_messenger.SendMessage(ZIPPO_WINDOW_QUIT);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_zipper_thread != NULL)
|
||||
m_zipper_thread->SuspendExternalZip();
|
||||
|
||||
zippoview->m_activity_view->Pause();
|
||||
|
||||
BAlert * quit_requester = new BAlert ("Stop or Continue", "Are you sure you want to "
|
||||
"stop creating this archive?", "Stop", "Continue",
|
||||
NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
|
||||
quit_requester->Go(m_alert_window_invoker);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoWindow::ReadSettings (void)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = m_zippo_settings.InitCheck();
|
||||
if (status != B_OK)
|
||||
error_message("m_zippo_settings.InitCheck()", status);
|
||||
|
||||
status = m_zippo_settings.ReadSettings();
|
||||
if (status != B_OK)
|
||||
error_message("m_zippo_settings.ReadSettings()", status);
|
||||
|
||||
BRect window_rect;
|
||||
|
||||
status = m_zippo_settings.FindRect("window_rect", & window_rect);
|
||||
if (status != B_OK)
|
||||
{
|
||||
error_message("m_settings_message->FindRect(window_rect)", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
ResizeTo (window_rect.Width(), window_rect.Height());
|
||||
MoveTo (window_rect.LeftTop());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZippoWindow::WriteSettings (void)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = m_zippo_settings.InitCheck();
|
||||
if (status != B_OK)
|
||||
error_message("m_zippo_settings.InitCheck()", status);
|
||||
|
||||
status = m_zippo_settings.MakeEmpty();
|
||||
if (status != B_OK)
|
||||
error_message("m_zippo_settings.MakeEmpty()", status);
|
||||
|
||||
status = m_zippo_settings.AddRect("window_rect", Frame());
|
||||
if (status != B_OK)
|
||||
{
|
||||
error_message("m_settings_message->AddRect(window_rect)", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = m_zippo_settings.WriteSettings();
|
||||
if (status != B_OK)
|
||||
{
|
||||
error_message("m_zippo_settings.WriteSettings()", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ZippoWindow::StartZipping (BMessage * a_message)
|
||||
{
|
||||
PRINT(("ZippoWindow::StartZipping()\n"));
|
||||
|
||||
zippoview->m_stop_button->SetEnabled(true);
|
||||
zippoview->m_activity_view->Start();
|
||||
|
||||
m_zipper_thread = new ZipperThread (a_message, this);
|
||||
m_zipper_thread->Start();
|
||||
|
||||
m_zipping_was_stopped = false;
|
||||
}
|
||||
|
||||
void
|
||||
ZippoWindow::StopZipping (void)
|
||||
{
|
||||
PRINT(("ZippoWindow::StopZipping()\n"));
|
||||
|
||||
m_zipping_was_stopped = true;
|
||||
|
||||
zippoview->m_stop_button->SetEnabled(false);
|
||||
|
||||
zippoview->m_activity_view->Stop();
|
||||
|
||||
m_zipper_thread->InterruptExternalZip();
|
||||
m_zipper_thread->Quit();
|
||||
|
||||
status_t status = B_OK;
|
||||
m_zipper_thread->WaitForThread (& status);
|
||||
m_zipper_thread = NULL;
|
||||
|
||||
zippoview->m_archive_name_view->SetText(" ");
|
||||
zippoview->m_zip_output_view->SetText("Stopped");
|
||||
|
||||
CloseWindowOrKeepOpen();
|
||||
}
|
||||
|
||||
bool
|
||||
ZippoWindow::IsZipping (void)
|
||||
{
|
||||
if (m_zipper_thread == NULL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ZippoWindow::CloseWindowOrKeepOpen (void)
|
||||
{
|
||||
if (m_got_refs_at_window_startup)
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
void
|
||||
ZippoWindow::Zoom (BPoint origin, float width, float height)
|
||||
{
|
||||
/*
|
||||
float archive_name_view_preferred_width;
|
||||
float zip_output_view_preferred_width;
|
||||
float throw_away_height;
|
||||
zippoview->GetPreferredSize(& archive_name_view_preferred_width, & throw_away_height);
|
||||
zippoview->GetPreferredSize(& zip_output_view_preferred_width, & throw_away_height);
|
||||
*/
|
||||
|
||||
// BStringView::GetPreferredSize appears to be broken,
|
||||
// so we have to use BView::StringWidth() instead
|
||||
|
||||
if (IsZipping())
|
||||
{
|
||||
float archive_name_view_preferred_width = zippoview->StringWidth(zippoview->m_archive_name_view->Text());
|
||||
float zip_output_view_preferred_width = zippoview->StringWidth(zippoview->m_zip_output_view->Text());
|
||||
|
||||
float the_wide_string;
|
||||
|
||||
if (zip_output_view_preferred_width > archive_name_view_preferred_width)
|
||||
the_wide_string = zip_output_view_preferred_width;
|
||||
else
|
||||
the_wide_string = archive_name_view_preferred_width;
|
||||
|
||||
ResizeTo(the_wide_string, Bounds().Height());
|
||||
}
|
||||
else
|
||||
{
|
||||
ResizeTo(230,110);
|
||||
}
|
||||
}
|
||||
|
46
src/add-ons/tracker/zipomatic/ZipOMaticWindow.h
Normal file
46
src/add-ons/tracker/zipomatic/ZipOMaticWindow.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef __ZIPPO_WINDOW_H__
|
||||
#define __ZIPPO_WINDOW_H__
|
||||
|
||||
#include <Window.h>
|
||||
#include <MenuBar.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuItem.h>
|
||||
|
||||
#include <ZipOMaticSettings.h>
|
||||
class ZippoView;
|
||||
class ZipperThread;
|
||||
|
||||
class ZippoWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
ZippoWindow (BMessage * a_message = NULL);
|
||||
~ZippoWindow (void);
|
||||
virtual void MessageReceived (BMessage * a_message);
|
||||
virtual bool QuitRequested (void);
|
||||
virtual void Zoom (BPoint origin, float width, float height);
|
||||
|
||||
bool IsZipping (void);
|
||||
|
||||
private:
|
||||
|
||||
status_t ReadSettings (void);
|
||||
status_t WriteSettings (void);
|
||||
|
||||
void StartZipping (BMessage * a_message);
|
||||
void StopZipping (void);
|
||||
|
||||
void CloseWindowOrKeepOpen (void);
|
||||
|
||||
ZippoView * zippoview;
|
||||
ZippoSettings m_zippo_settings;
|
||||
ZipperThread * m_zipper_thread;
|
||||
|
||||
bool m_got_refs_at_window_startup;
|
||||
bool m_zipping_was_stopped;
|
||||
|
||||
BMessage * m_alert_invoker_message;
|
||||
BInvoker * m_alert_window_invoker;
|
||||
};
|
||||
|
||||
#endif // __ZIPPO_WINDOW_H__
|
388
src/add-ons/tracker/zipomatic/ZipOMaticZipper.cpp
Normal file
388
src/add-ons/tracker/zipomatic/ZipOMaticZipper.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
// license: public domain
|
||||
// authors: jonas.sundstrom@kirilla.com
|
||||
//
|
||||
// exception: ZipperThread::PipeCommand()
|
||||
// written by Peter Folk, published in the BeDevTalk mailinglist FAQ
|
||||
// License unknown, most likely public domain
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include <Path.h>
|
||||
|
||||
#include <ZipOMaticZipper.h>
|
||||
#include <ZipOMaticWindow.h>
|
||||
#include <ZipOMaticMisc.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
const char * ZipperThreadName = "ZipperThread";
|
||||
|
||||
|
||||
ZipperThread::ZipperThread (BMessage * a_refs_message, BWindow * a_window)
|
||||
: GenericThread(ZipperThreadName, B_NORMAL_PRIORITY, a_refs_message),
|
||||
m_window (a_window),
|
||||
m_window_messenger (new BMessenger(NULL, a_window)),
|
||||
m_zip_process_thread_id (-1),
|
||||
m_std_in (-1),
|
||||
m_std_out (-1),
|
||||
m_std_err (-1),
|
||||
m_zip_output (NULL),
|
||||
m_zip_output_string (),
|
||||
m_zip_output_buffer (new char [4096])
|
||||
{
|
||||
PRINT(("ZipperThread()\n"));
|
||||
|
||||
m_thread_data_store = new BMessage (* a_refs_message); // leak?
|
||||
// prevents bug with B_SIMPLE_DATA
|
||||
// (drag&drop messages)
|
||||
}
|
||||
|
||||
ZipperThread::~ZipperThread()
|
||||
{
|
||||
delete m_window_messenger;
|
||||
delete [] m_zip_output_buffer;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::ThreadStartup (void)
|
||||
{
|
||||
PRINT(("ZipperThread::ThreadStartup()\n"));
|
||||
|
||||
// init
|
||||
status_t status = B_OK;
|
||||
entry_ref ref;
|
||||
entry_ref last_ref;
|
||||
bool same_folder = true;
|
||||
|
||||
BString zip_archive_filename = "Archive.zip";
|
||||
|
||||
// do all refs have the same parent dir?
|
||||
type_code ref_type = B_REF_TYPE;
|
||||
int32 ref_count = 0;
|
||||
|
||||
status = m_thread_data_store->GetInfo("refs", & ref_type, & ref_count);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
for (int index = 0; index < ref_count ; index++)
|
||||
{
|
||||
m_thread_data_store->FindRef("refs", index, & ref);
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
BEntry entry (& ref);
|
||||
if (entry.IsSymLink())
|
||||
{
|
||||
entry.SetTo(& ref, true);
|
||||
entry_ref target;
|
||||
entry.GetRef(& target);
|
||||
if (last_ref.directory != target.directory)
|
||||
{
|
||||
same_folder = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (last_ref.directory != ref.directory)
|
||||
{
|
||||
same_folder = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
last_ref = ref;
|
||||
}
|
||||
|
||||
// change active dir
|
||||
if (same_folder)
|
||||
{
|
||||
BEntry entry (& last_ref);
|
||||
BPath path;
|
||||
entry.GetParent(& entry);
|
||||
entry.GetPath(& path);
|
||||
chdir(path.Path());
|
||||
}
|
||||
else
|
||||
{
|
||||
BPath path;
|
||||
if (find_directory(B_DESKTOP_DIRECTORY, & path) == B_OK)
|
||||
chdir (path.Path());
|
||||
}
|
||||
|
||||
// archive filename
|
||||
if (ref_count == 1)
|
||||
{
|
||||
zip_archive_filename = last_ref.name;
|
||||
zip_archive_filename += ".zip";
|
||||
}
|
||||
|
||||
int32 argc = ref_count + 3;
|
||||
const char ** argv = new const char * [argc + 1];
|
||||
|
||||
argv[0] = strdup("/bin/zip");
|
||||
argv[1] = strdup("-ry");
|
||||
argv[2] = strdup(zip_archive_filename.String());
|
||||
|
||||
|
||||
// files to zip
|
||||
for (int ref_index = 0; ref_index < ref_count ; ref_index++)
|
||||
{
|
||||
m_thread_data_store->FindRef("refs", ref_index, & ref);
|
||||
|
||||
if (same_folder)
|
||||
{
|
||||
argv[3 + ref_index] = strdup(ref.name); // just the file name
|
||||
}
|
||||
else
|
||||
{
|
||||
BPath path (& ref);
|
||||
BString file = path.Path();
|
||||
argv[3 + ref_index] = strdup(path.Path()); // full path
|
||||
}
|
||||
}
|
||||
|
||||
argv[argc] = NULL;
|
||||
|
||||
m_zip_process_thread_id = PipeCommand (argc, argv, m_std_in, m_std_out, m_std_err);
|
||||
|
||||
delete [] argv;
|
||||
|
||||
if (m_zip_process_thread_id < 0)
|
||||
return (m_zip_process_thread_id);
|
||||
|
||||
resume_thread (m_zip_process_thread_id);
|
||||
|
||||
m_zip_output = fdopen (m_std_out, "r");
|
||||
|
||||
zip_archive_filename.Prepend("Creating archive: ");
|
||||
|
||||
SendMessageToWindow ('strt', "archive_filename", zip_archive_filename.String());
|
||||
SendMessageToWindow ('outp', "zip_output", "Preparing to archive");
|
||||
|
||||
PRINT(("\n"));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::ExecuteUnit (void)
|
||||
{
|
||||
//PRINT(("ZipperThread::ExecuteUnit()\n"));
|
||||
|
||||
// read output from /bin/zip
|
||||
// send it to window
|
||||
|
||||
char * output_string;
|
||||
output_string = fgets(m_zip_output_buffer , 4096-1, m_zip_output);
|
||||
|
||||
if (output_string == NULL)
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
char * new_line_ptr = strrchr(output_string, '\n');
|
||||
if (new_line_ptr != NULL)
|
||||
*new_line_ptr = '\0';
|
||||
|
||||
if (! strncmp(" a", m_zip_output_buffer, 3))
|
||||
{
|
||||
m_zip_output_buffer[2] = 'A';
|
||||
SendMessageToWindow ('outp', "zip_output", output_string + 2);
|
||||
}
|
||||
else if (! strncmp("up", m_zip_output_buffer, 2))
|
||||
{
|
||||
m_zip_output_buffer[0] = 'U';
|
||||
SendMessageToWindow ('outp', "zip_output", output_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageToWindow ('outp', "zip_output", output_string);
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::ThreadShutdown (void)
|
||||
{
|
||||
PRINT(("ZipperThread::ThreadShutdown()\n"));
|
||||
|
||||
close(m_std_in);
|
||||
close(m_std_out);
|
||||
close(m_std_err);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ZipperThread::ThreadStartupFailed (status_t a_status)
|
||||
{
|
||||
error_message("ZipperThread::ThreadStartupFailed() \n", a_status);
|
||||
|
||||
Quit();
|
||||
}
|
||||
|
||||
void
|
||||
ZipperThread::ExecuteUnitFailed (status_t a_status)
|
||||
{
|
||||
error_message("ZipperThread::ExecuteUnitFailed() \n", a_status);
|
||||
|
||||
|
||||
if (a_status == EOF)
|
||||
{
|
||||
// thread has finished, been quit or killed, we don't know
|
||||
SendMessageToWindow ('exit');
|
||||
}
|
||||
else
|
||||
{
|
||||
// explicit error - communicate error to Window
|
||||
SendMessageToWindow ('exrr');
|
||||
}
|
||||
|
||||
Quit();
|
||||
}
|
||||
|
||||
void
|
||||
ZipperThread::ThreadShutdownFailed (status_t a_status)
|
||||
{
|
||||
error_message("ZipperThread::ThreadShutdownFailed() \n", a_status);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZipperThread::MakeShellSafe (BString * a_string)
|
||||
{
|
||||
a_string->CharacterEscape("\"$`", '\\');
|
||||
a_string->Prepend("\"");
|
||||
a_string->Append("\"");
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::ProcessRefs (BMessage * msg)
|
||||
{
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
thread_id
|
||||
ZipperThread::PipeCommand (int argc, const char **argv, int & in, int & out, int & err, const char **envp)
|
||||
{
|
||||
// This function written by Peter Folk <pfolk@uni.uiuc.edu>
|
||||
// and published in the BeDevTalk FAQ
|
||||
// http://www.abisoft.com/faq/BeDevTalk_FAQ.html#FAQ-209
|
||||
|
||||
// Save current FDs
|
||||
int old_in = dup(0);
|
||||
int old_out = dup(1);
|
||||
int old_err = dup(2);
|
||||
|
||||
int filedes[2];
|
||||
|
||||
/* Create new pipe FDs as stdin, stdout, stderr */
|
||||
pipe(filedes); dup2(filedes[0],0); close(filedes[0]);
|
||||
in=filedes[1]; // Write to in, appears on cmd's stdin
|
||||
pipe(filedes); dup2(filedes[1],1); close(filedes[1]);
|
||||
out=filedes[0]; // Read from out, taken from cmd's stdout
|
||||
pipe(filedes); dup2(filedes[1],2); close(filedes[1]);
|
||||
err=filedes[0]; // Read from err, taken from cmd's stderr
|
||||
|
||||
// "load" command.
|
||||
thread_id ret = load_image(argc, argv, envp);
|
||||
// thread ret is now suspended.
|
||||
|
||||
PRINT(("load_image() thread_id: %ld\n", ret));
|
||||
|
||||
// Restore old FDs
|
||||
close(0); dup(old_in); close(old_in);
|
||||
close(1); dup(old_out); close(old_out);
|
||||
close(2); dup(old_err); close(old_err);
|
||||
|
||||
/* Theoretically I should do loads of error checking, but
|
||||
the calls aren't very likely to fail, and that would
|
||||
muddy up the example quite a bit. YMMV. */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
ZipperThread::SendMessageToWindow (uint32 a_msg_what, const char * a_string_name, const char * a_string_value)
|
||||
{
|
||||
BMessage msg (a_msg_what);
|
||||
|
||||
if (! (a_string_name == NULL || a_string_value == NULL))
|
||||
msg.AddString(a_string_name, a_string_value);
|
||||
|
||||
m_window_messenger->SendMessage(& msg);
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::SuspendExternalZip (void)
|
||||
{
|
||||
PRINT(("ZipperThread::SuspendExternalZip()\n"));
|
||||
|
||||
status_t status = B_OK;
|
||||
thread_info zip_thread_info;
|
||||
status = get_thread_info (m_zip_process_thread_id, & zip_thread_info);
|
||||
BString thread_name = zip_thread_info.name;
|
||||
|
||||
if (status == B_OK && thread_name == "zip")
|
||||
return suspend_thread (m_zip_process_thread_id);
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::ResumeExternalZip (void)
|
||||
{
|
||||
PRINT(("ZipperThread::ResumeExternalZip()\n"));
|
||||
|
||||
status_t status = B_OK;
|
||||
thread_info zip_thread_info;
|
||||
status = get_thread_info (m_zip_process_thread_id, & zip_thread_info);
|
||||
BString thread_name = zip_thread_info.name;
|
||||
|
||||
if (status == B_OK && thread_name == "zip")
|
||||
return resume_thread (m_zip_process_thread_id);
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::InterruptExternalZip (void)
|
||||
{
|
||||
PRINT(("ZipperThread::InterruptExternalZip()\n"));
|
||||
|
||||
status_t status = B_OK;
|
||||
thread_info zip_thread_info;
|
||||
status = get_thread_info (m_zip_process_thread_id, & zip_thread_info);
|
||||
BString thread_name = zip_thread_info.name;
|
||||
|
||||
if (status == B_OK && thread_name == "zip")
|
||||
{
|
||||
status = B_OK;
|
||||
status = send_signal (m_zip_process_thread_id, SIGINT);
|
||||
WaitOnExternalZip();
|
||||
return status;
|
||||
}
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t
|
||||
ZipperThread::WaitOnExternalZip (void)
|
||||
{
|
||||
PRINT(("ZipperThread::WaitOnExternalZip()\n"));
|
||||
|
||||
status_t status = B_OK;
|
||||
thread_info zip_thread_info;
|
||||
status = get_thread_info (m_zip_process_thread_id, & zip_thread_info);
|
||||
BString thread_name = zip_thread_info.name;
|
||||
|
||||
if (status == B_OK && thread_name == "zip")
|
||||
return wait_for_thread (m_zip_process_thread_id, & status);
|
||||
else
|
||||
return status;
|
||||
}
|
61
src/add-ons/tracker/zipomatic/ZipOMaticZipper.h
Normal file
61
src/add-ons/tracker/zipomatic/ZipOMaticZipper.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef __ZIPOMATIC_ZIPPER_H__
|
||||
#define __ZIPOMATIC_ZIPPER_H__
|
||||
|
||||
#include <Message.h>
|
||||
#include <Volume.h>
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
#include <OS.h>
|
||||
#include <FindDirectory.h>
|
||||
|
||||
#include <GenericThread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern const char * ZipperThreadName;
|
||||
|
||||
class ZipperThread : public GenericThread
|
||||
{
|
||||
public:
|
||||
ZipperThread (BMessage * a_refs_message, BWindow * a_window);
|
||||
~ZipperThread ();
|
||||
|
||||
status_t SuspendExternalZip (void);
|
||||
status_t ResumeExternalZip (void);
|
||||
status_t InterruptExternalZip (void);
|
||||
status_t WaitOnExternalZip (void);
|
||||
|
||||
private:
|
||||
|
||||
virtual status_t ThreadStartup (void);
|
||||
virtual status_t ExecuteUnit (void);
|
||||
virtual status_t ThreadShutdown (void);
|
||||
|
||||
virtual void ThreadStartupFailed (status_t a_status);
|
||||
virtual void ExecuteUnitFailed (status_t a_status);
|
||||
virtual void ThreadShutdownFailed (status_t a_status);
|
||||
|
||||
status_t ProcessRefs (BMessage * msg);
|
||||
void MakeShellSafe (BString * a_string);
|
||||
|
||||
thread_id PipeCommand (int argc, const char **argv,
|
||||
int & in, int & out, int & err,
|
||||
const char **envp = (const char **) environ);
|
||||
|
||||
void SendMessageToWindow (uint32 a_msg_what,
|
||||
const char * a_string_name = NULL,
|
||||
const char * a_string_value = NULL);
|
||||
|
||||
BWindow * m_window;
|
||||
BMessenger * m_window_messenger;
|
||||
|
||||
int32 m_zip_process_thread_id;
|
||||
int m_std_in;
|
||||
int m_std_out;
|
||||
int m_std_err;
|
||||
FILE * m_zip_output;
|
||||
BString m_zip_output_string;
|
||||
char * m_zip_output_buffer;
|
||||
};
|
||||
|
||||
#endif // __ZIPOMATIC_ZIPPER_H__
|
||||
|
Loading…
x
Reference in New Issue
Block a user