[haiku-commits] r34044 - haiku/trunk/src/add-ons/tracker/zipomatic

Author: kirilla
Date: 2009-11-14 22:49:35 +0100 (Sat, 14 Nov 2009)
New Revision: 34044
Changeset: http://dev.haiku-os.org/changeset/34044/haiku

Removed:
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticMisc.cpp
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticSettings.cpp
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticSettings.h
Modified:
   haiku/trunk/src/add-ons/tracker/zipomatic/Jamfile
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.cpp
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.h
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticMisc.h
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.cpp
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.h
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipperThread.cpp
   haiku/trunk/src/add-ons/tracker/zipomatic/ZipperThread.h
Log:
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.

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/Jamfile   2009-11-14 21:08:33 UTC 
(rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/Jamfile   2009-11-14 21:49:35 UTC 
(rev 34044)
@@ -6,8 +6,6 @@
        GenericThread.cpp
        ZipOMatic.cpp
        ZipOMaticActivity.cpp
-       ZipOMaticMisc.cpp
-       ZipOMaticSettings.cpp
        ZipOMaticWindow.cpp
        ZipperThread.cpp
 

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.cpp
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.cpp     2009-11-14 
21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.cpp     2009-11-14 
21:49:35 UTC (rev 34044)
@@ -11,7 +11,6 @@
 
 #include <Alert.h>
 #include <Roster.h>
-#include <Screen.h>
 #include <TrackerAddOnAppLaunch.h>
 
 #include "ZipOMaticMisc.h"
@@ -31,45 +30,27 @@
 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 @@
        switch (message->what) {
                case ZIPPO_WINDOW_QUIT:
                {
-                       BRect frame;
-                       if (message->FindRect("frame", &frame) == B_OK)
-                               fWindowFrame = frame;
                        snooze(200000);
                        if (CountWindows() == 0)
                                Quit();
@@ -105,7 +83,7 @@
                        if (message->FindInt32("which", &button) == B_OK)
                                if (button == 0) {
                                        _StopZipping();
-                               } else  {
+                               } else {
                                        if (CountWindows() == 0)
                                                Quit();
                                }
@@ -120,7 +98,7 @@
 
 
 bool
-ZipOMatic::QuitRequested  (void)
+ZipOMatic::QuitRequested(void)
 {
        if (CountWindows() <= 0)
                return true;
@@ -208,43 +186,42 @@
 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;
+
+               zWindow = dynamic_cast<ZippoWindow*>(bWindow);
+               if (zWindow == NULL)
+                       continue;
+
+               list.AddItem(zWindow);
                
-               if (window->Lock()) {
-                       if (!window->IsZipping()) {
-                               foundNonBusyWindow = true;
+               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()
-               }
-               
-               ZippoWindow * window = new ZippoWindow(fWindowFrame, message);
-               window->Show();
+
+       if (message) {
+               zWindow = new ZippoWindow(list);
+               zWindow->PostMessage(message);
+       } else {
+               zWindow = new ZippoWindow(list, true);
        }
+
+       zWindow->Show();
 }
 
 
@@ -282,93 +259,3 @@
        }       
 }
 
-
-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();
-               }
-       }       
-}
-

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.h
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.h       2009-11-14 
21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMatic.h       2009-11-14 
21:49:35 UTC (rev 34044)
@@ -5,11 +5,8 @@
 #include <Application.h>
 #include <Invoker.h>
 #include <Message.h>
-#include <Rect.h>
 
-#include "ZipOMaticSettings.h"
 
-
 class ZipOMatic : public BApplication
 {
 public:
@@ -22,18 +19,13 @@
        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_

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp     
2009-11-14 21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp     
2009-11-14 21:49:35 UTC (rev 34044)
@@ -88,7 +88,7 @@
        uchar tmp = fPattern.data[7];
 
        for (int j = 7; j > 0; --j)
-               fPattern.data[j] = fPattern.data[j-1];
+               fPattern.data[j] = fPattern.data[j - 1];
        
        fPattern.data[0] = tmp;
        
@@ -103,10 +103,6 @@
        BRect bitmapRect = fBitmap->Bounds();
 
        if (bitmapRect != viewRect) {
-               printf("Activity::Draw(): bitmapRect != viewRect\n");
-               bitmapRect.PrintToStream();
-               viewRect.PrintToStream();
-
                delete fBitmap;
                _CreateBitmap();
        }
@@ -138,7 +134,7 @@
                fBitmapView->SetHighColor(color);
 
                // draw the pole
-               rect.InsetBy(2,2);
+               rect.InsetBy(2, 2);
                fBitmapView->FillRect(rect, fPattern);  
                
                // draw frame
@@ -198,19 +194,19 @@
                fBitmapView->SetDrawingMode(B_OP_SUBTRACT);
                fBitmapView->StrokeRect(rect);
        
-               rect.InsetBy(1,1);
+               rect.InsetBy(1, 1);
                _LightenBitmapHighColor(& color);
                fBitmapView->StrokeRect(rect);
                
-               rect.InsetBy(1,1);
+               rect.InsetBy(1, 1);
                _LightenBitmapHighColor(& color);
                fBitmapView->StrokeRect(rect);
                
-               rect.InsetBy(1,1);
+               rect.InsetBy(1, 1);
                _LightenBitmapHighColor(& color);
                fBitmapView->StrokeRect(rect);
                
-               rect.InsetBy(1,1);
+               rect.InsetBy(1, 1);
                _LightenBitmapHighColor(& color);
                fBitmapView->StrokeRect(rect);
                

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticMisc.h
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticMisc.h   2009-11-14 
21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticMisc.h   2009-11-14 
21:49:35 UTC (rev 34044)
@@ -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
 

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.cpp
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.cpp       
2009-11-14 21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.cpp       
2009-11-14 21:49:35 UTC (rev 34044)
@@ -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 @@
                        .End()
                .End();
 
-       if (refs != NULL) {
-               fWindowGotRefs = true;
-               _StartZipping(refs);
-       }
+       _FindBestPlacement();
 }
 
 
@@ -88,9 +87,6 @@
 {
        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 @@
                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,11 +201,14 @@
                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);
-               
+
                return false;
        }
 }
@@ -261,7 +263,155 @@
 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;
+}
+

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.h
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.h 2009-11-14 
21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipOMaticWindow.h 2009-11-14 
21:49:35 UTC (rev 34044)
@@ -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 @@
                        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;
                        

Modified: haiku/trunk/src/add-ons/tracker/zipomatic/ZipperThread.cpp
===================================================================
--- haiku/trunk/src/add-ons/tracker/zipomatic/ZipperThread.cpp  2009-11-14 
21:08:33 UTC (rev 34043)
+++ haiku/trunk/src/add-ons/tracker/zipomatic/ZipperThread.cpp  2009-11-14 
21:49:35 UTC (rev 34044)
@@ -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 @@
        fOutputFile(NULL)
 {
        fThreadDataStore = new BMessage(*refsMessage);
-               // leak?
-               // prevents bug with B_SIMPLE_DATA
-               // (drag&drop messages)
 }
 
 
@@ -48,9 +47,6 @@
 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 @@
        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 @@
                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 @@
                        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 @@
        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 @@
        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 @@
 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 @@
        close(fStdOut); 
        close(fStdErr);
 
+       // _SelectInTracker();
+
        return B_OK;
 }
 
@@ -192,7 +214,6 @@
 void
 ZipperThread::ThreadStartupFailed(status_t status)
 {
-       ErrorMessage("ZipperThread::ThreadStartupFailed() \n", status);
        Quit();
 }
 
@@ -200,8 +221,6 @@
 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 @@
 void
 ZipperThread::ThreadShutdownFailed(status_t status)
 {
-       ErrorMessage("ZipperThread::ThreadShutdownFailed() \n", status);
+       fprintf(stderr, "ZipperThread::ThreadShutdownFailed(): %s\n",
+               strerror(status));
 }
 
 
@@ -234,68 +254,78 @@
 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@xxxxxxxxxxxx>
-       // and published in the BeDevTalk FAQ
-       // http://www.abisoft.com/faq/BeDevTalk_FAQ.html#FAQ-209
+       static BLocker lock;
 
-       thread_id thread;
+       if (lock.Lock()) {
+               // This function was originally written by Peter Folk
+               // <pfolk@xxxxxxxxxxxx> and published in the BeDevTalk FAQ
+               // http://www.abisoft.com/faq/BeDevTalk_FAQ.html#FAQ-209
 
-       // Save current FDs
-       int oldIn = dup(STDIN_FILENO);
-       int oldOut = dup(STDOUT_FILENO);
-       int oldErr = dup(STDERR_FILENO);
+               thread_id thread;
 
-       int inPipe[2], outPipe[2], errPipe[2];
+               // Save current FDs
+               int oldIn = dup(STDIN_FILENO);
+               int oldOut = dup(STDOUT_FILENO);
+               int oldErr = dup(STDERR_FILENO);
 
-       // Create new pipe FDs as stdin, stdout, stderr
-       if (pipe(inPipe) < 0)
-               goto err1;
-       if (pipe(outPipe) < 0)
-               goto err2;
-       if (pipe(errPipe) < 0)
-               goto err3;
+               int inPipe[2], outPipe[2], errPipe[2];
 
-       errno = 0;
+               // Create new pipe FDs as stdin, stdout, stderr
+               if (pipe(inPipe) < 0)
+                       goto err1;
+               if (pipe(outPipe) < 0)
+                       goto err2;
+               if (pipe(errPipe) < 0)
+                       goto err3;
 
-       // replace old stdin/stderr/stdout
-       dup2(inPipe[0], STDIN_FILENO);
-       close(inPipe[0]);
-       dup2(outPipe[1], STDOUT_FILENO);
-       close(outPipe[1]);
-       dup2(errPipe[1], STDERR_FILENO);
-       close(errPipe[1]);
+               errno = 0;
 
-       if (errno == 0) {
-               in = inPipe[1];         // Write to in, appears on cmd's stdin 
-               out = outPipe[0];       // Read from out, taken from cmd's 
stdout 
-               err = errPipe[0];       // Read from err, taken from cmd's 
stderr 
+               // replace old stdin/stderr/stdout
+               dup2(inPipe[0], STDIN_FILENO);
+               close(inPipe[0]);
+               dup2(outPipe[1], STDOUT_FILENO);
+               close(outPipe[1]);
+               dup2(errPipe[1], STDERR_FILENO);
+               close(errPipe[1]);
 
-               // execute command
-               thread = load_image(argc, argv, envp);
+               if (errno == 0) {
+                       in = inPipe[1];         // Write to in, appears on 
cmd's stdin 
+                       out = outPipe[0];       // Read from out, taken from 
cmd's stdout 
+                       err = errPipe[0];       // Read from err, taken from 
cmd's stderr 
+
+                       // execute command
+                       thread = load_image(argc, argv, envp);
+               } else {
+                       thread = errno;
+               }
+
+               // Restore old FDs
+               dup2(oldIn, STDIN_FILENO);
+               close(oldIn);
+               dup2(oldOut, STDOUT_FILENO);
+               close(oldOut);
+               dup2(oldErr, STDERR_FILENO);
+               close(oldErr);
+
+               lock.Unlock();
+               return thread;
+
+       err3:
+               close(outPipe[0]);
+               close(outPipe[1]);
+       err2:
+               close(inPipe[0]);
+               close(inPipe[1]);
+       err1:
+               close(oldIn);
+               close(oldOut);
+               close(oldErr);
+
+               lock.Unlock();
+               return errno;
        } else {

[... truncated: 185 lines follow ...]

Other related posts:

  • » [haiku-commits] r34044 - haiku/trunk/src/add-ons/tracker/zipomatic - jonas