File: programming/cocoa/UKProgressPanel.zip/UKProgressPanel_02/UKProgressPanel/UKProgressPanel.m


/* =============================================================================
	POJECT:		UKProgressPanel
	PURPOSE:	MT-Newswatcher/Finder-style progress window for keeping the
				user current on concurrently running tasks.
	AUTHORS:	M. Uli Kusterer (UK), (c) 2003, all rights reserved.
	
	REQUIRES:	UKProgressPanel.h
				UKProgressPanel.nib
				UKProgressPanel.strings
				UKProgressPanelTask.h
				UKProgressPanelTask.m
				(UKProgressPanelTask.nib)
   ========================================================================== */
 
/* -----------------------------------------------------------------------------
	Headers:
   -------------------------------------------------------------------------- */
 
#import "UKProgressPanel.h"
#import "UKProgressPanelTask.h"
#import "UKMainThreadProxy.h"
 
 
/* -----------------------------------------------------------------------------
	Globals:
   -------------------------------------------------------------------------- */// Here we keep track of our shared panel instance (singleton pattern).
// Users will want to use threads with this. We need a mutex lock to avoid several progress panels and such stuff.
/* -----------------------------------------------------------------------------
	sharedProgressPanel:
		Returns a pointer to our shared UKProgressPanel instance, creating
		it if none exists yet.
   -------------------------------------------------------------------------- *//* -----------------------------------------------------------------------------
	Constructor:
		Loads the progress window from UKProgressPanel.nib and slightly changes
		its behavior in ways that aren't possible through the NIB.
   -------------------------------------------------------------------------- */
		
/**		\note   This window's behavior has been chosen intentionally. It uses a
		utility window with small title bar since it's not associated with a
		document and isn't one itself, but it still performs the function of a
		palette.
		
		It is set not to hide when the application is in the background since
		the user may want to check whether the app has finished while it was
		in the background.
		
		It is also set to be at normal window level because the default level
		for utility windows is a system-wide floater, which would mean our
		progress window would obscure other apps' windows. It is also at normal
		window level to allow that the user send it behind another window when
		working.
*/// We're responsible for releasing any top-level objects in the NIB (right now only our NSPanel).
// Allow checking on progress while app's in back.
// Allow sending it behind documents.
		[tlw setReleasedWhenClosed: NO];		// Only hide on close box click.
// This aray doesn't retain its objects.
		
		//[taskContentView setFlipped: YES];
/* -----------------------------------------------------------------------------
	Destructor:
		Note that you may *not* destruct this window while any tasks listed
		in it are still running. To avoid circular dependencies, this window
		does not know which tasks it contains. It does know about their content
		views, though.
   -------------------------------------------------------------------------- */// Make sure user can create a new shared instance if desired.
	[gUKProgressPanelThreadLock unlock];
	
	[unretainedTasks release];
	
	[super dealloc];
}
 
 
/* -----------------------------------------------------------------------------
	orderFront:
		Passes the message on to the task list panel.
   -------------------------------------------------------------------------- *//* -----------------------------------------------------------------------------
	stopAllTasks:
		Cancels all the tasks that are currently running.
   -------------------------------------------------------------------------- *//* -----------------------------------------------------------------------------
	addProgressPanelTask:
		This is called by UKProgressPanelTasks when they are created. It adds
		the task's view to the list in the window above the current tasks.
		Then it brings the window to the front so the user sees that there's
		a new task in progress. Since the window can't become key, the user
		shouldn't be too annoyed by this, as keyboard focus etc. aren't
		changed.
		
		This also updates the "n tasks in progress..." message at the top
		of the window.
		
		Must be called on the main thread.
   -------------------------------------------------------------------------- */// Position the new box above all others:
		lastBox.origin.y += lastBox.size.height;							// Move box up one slot.
		[[theElement progressTaskView] setFrameOrigin: lastBox.origin];		// Move new field to this position.
		
		// Calculate total height up to our new box:
// Make sure we get a current list & current count.
	
	[taskContentView setFrameSize: newSize];				// Make content view that size.
	
	// Scroll new box into view:
	[taskContentView scrollRectToVisible: [[theElement progressTaskView] frame]];
	
	// Update "number of tasks" status display:
"%u tasks in progress...",@"UKProgressPanel"/* -----------------------------------------------------------------------------
	removeProgressPanelTask:
		This is called by UKProgressPanelTasks when they are destroyed. It
		removes the task's view from the list in the window, moving down any
		views above it.
		
		This also updates the "n tasks in progress..." message at the top
		of the window.
		
		Must be called on the main thread.
   -------------------------------------------------------------------------- */// Update "number of tasks" status display:
"No active tasks.",@"UKProgressPanel""%u tasks in progress...",@"UKProgressPanel"// Move down elements above the one we're removing:
// Resize scroller's content area:
// Leave at same position (if outside of screen it will placed on screen automatically)
	theRect.origin.x = [sender frame].origin.x;
	
	// y of origin has to adjusted with the height difference to leave the
	//  top of the window at the same place. 16 for the scrollbar and 17 for the
	//	status text
// Calculate the optimal height (if larger than screen this will taken care of automatically)
#if UK_PROGRESS_PANEL_SAFARI_STYLE
"UKListProgressPanel";
	#else
"UKProgressPanel";
	#endif
/* -----------------------------------------------------------------------------
	orderFrontProgressPanel:
		Category on NSApplication that adds a method for bringing the shared
		progress panel to front, creating it if there isn't one yet. You can
		use this as the action of a menu item (suggested name "Tasks") in your
		"Window" menu to allow that the user re-show the progress window once
		he has hidden it by clicking its close box.
   -------------------------------------------------------------------------- */

This code uses the PclZip Zip File reading code, which is subject to the GNU LGPL. It also uses the GeSHi syntax highlighter, subject to the GPL. Ask if you want this for your own web site, it's free.