home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 16.4 KB | 535 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Part.cpp
- // Release Version: $ ODF 2 $
- //
- // Author: Henri Lamiraux
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "Bitmap.hpp"
-
- #ifndef PART_H
- #include "Part.h"
- #endif
-
- #ifndef BINDING_K
- #include "Binding.k"
- #endif
-
- #ifndef FRAME_H
- #include "Frame.h"
- #endif
-
- #ifndef SELECT_H
- #include "Select.h"
- #endif
-
- #ifndef CONTENT_H
- #include "Content.h"
- #endif
-
- #ifndef DEFINES_K
- #include "Defines.k"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWPRTITE_H
- #include "FWPrtIte.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWABOUT_H
- #include "FWAbout.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWSUSINK_H
- #include "FWSUSink.h"
- #endif
-
- #ifndef FWPICTUR_H
- #include "FWPictur.h"
- #endif
-
- #ifndef FWEVENT_H
- #include "FWEvent.h"
- #endif
-
- #ifndef FWBARRAY_H
- #include "FWBArray.h"
- #endif
-
- #ifndef FWFILEAC_H
- #include "FWFileAc.h"
- #endif
-
- #ifndef SLMixOS_H
- #include "SLMixOS.h"
- #endif
-
- // ----- Foundation Layer -----
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- #ifndef FWMEMORY_H
- #include "FWMemory.h"
- #endif
-
- #ifndef FWSUSINK_H
- #include "FWSUSink.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- // ----- Macintosh Includes -----
-
- #if defined(FW_BUILD_MAC) && !defined(__DRAG__)
- #include <Drag.h>
- #endif
-
- // ----- Cyberdog Support -----
-
- #if FW_SUPPORTS_CYBERDOG
- #include <Cyberdog.h>
- #include <CyberItem.xh>
- #include <CyberSession.xh>
- #include <CyberStream.xh>
- #include <ParameterSet.xh>
-
- #ifndef FWCYPART_H
- #include "FWCyPart.h"
- #endif
-
- #ifndef FWCYSTRM_H
- #include "FWCyStrm.h"
- #endif
-
- #include "FWSaveAs.h"
- #include "odfjpeg.h"
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfbitmap
- #endif
-
- //========================================================================================
- // class CBitmapPart
- //========================================================================================
-
- FW_DEFINE_AUTO(CBitmapPart)
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::CBitmapPart
- //----------------------------------------------------------------------------------------
- // CBitmapPart constructor
-
- CBitmapPart::CBitmapPart(ODPart* odPart) :
- FW_CPart(odPart, FW_gInstance, kPartInfoID),
- #if FW_SUPPORTS_CYBERDOG
- fHelper (kODNULL),
- fReloadContinuously (false),
- #endif
- fBitmapContent(NULL),
- fBitmapPresentation(NULL)
- {
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::~CBitmapPart
- //----------------------------------------------------------------------------------------
- // CBitmapPart destructor
-
- CBitmapPart::~CBitmapPart()
- {
- FW_START_DESTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::Initialize
- //----------------------------------------------------------------------------------------
- // ODF Method
-
- void CBitmapPart::Initialize(Environment* ev, ODStorageUnit* storageUnit, FW_Boolean fromStorage)
- {
- // ----- Call first inherited -----
- FW_CPart::Initialize(ev, storageUnit, fromStorage);
-
- #if FW_SUPPORTS_CYBERDOG
- /*
- ----- Cyberdog: Implementing your Cyberdog Part Extension -----
-
- The first thing you want to do is to add support for the CyberPartExtension
- (for details on this, see chapter 4 of the Cyberdog Programmer’s Guide,
- "Creating a Cyberdog Display Part", under the heading "Implementing your
- Cyberdog Part Extension").
-
- ODF encapsulates all the CyberPartExtension support in the
- FW_CCyberdogHelper class. You’ll want to create an instance of
- FW_CCyberdogHelper along with your part. Create the instance in your part’s
- Initialize method, like so:
- */
- fHelper = ::FW_SupportCyberdogIfPresent (ev, this, FW_kUseCyberMenus, cCyberdogCommands, FW_kUseNavigator);
- /*
- FW_SupportCyberdogIfPresent returns null if Cyberdog is not installed.
- It is NOT necessary to delete the helper because it is an eventhandler
- and will be deleted by FW_CPart automatically.
-
- You may choose whether you want the Cyberdog menus displayed in your part or
- not (FW_kUseCyberMenus); you may also choose whether you want your part to
- be displayed in the Cyberdog navigator/browser (FW_kUseNavigator).
-
- If you want the Cyberdog menus then you must reserve a range of command
- numbers for them as well. ODFBitmap defines cCyberdogCommands in Defines.k.
-
- ----- Creating a Stream for Downloading -----
-
- When a Cyberdog item is opened, Cyberdog calls your part extension's
- SetCyberItem method. ODF will then call the helper's DoSetCyberItem
- method. You may register a function to be called automatically. Here
- "LoadCyberItem" will be called, and "this" will be passed to it.
- Notice that for ODFBitmap, LoadCyberItem is a static member function, not
- a global function, but it makes no difference.
- */
- if (fHelper)
- fHelper->SetLoadCyberItemThreadProcedure (LoadCyberItem, this);
- #endif
-
- // ----- Register our Presentations
- fBitmapPresentation = RegisterPresentation(ev,
- "Apple:Presentation:ODFBitmap",
- TRUE,
- FW_NEW(CBitmapSelection, (ev, this, fBitmapContent)));
-
- // ----- Register our other kinds -----
- RegisterKind(ev, kPICTOSType, kODPlatformDataType, FW_kDataInterchangeStorage, FW_kImportExportEnabled);
- RegisterKind(ev, kPICTOSType, kODPlatformFileType, FW_kAllStorage, FW_kImport);
- RegisterKind(ev, kJPEGOSType, kODPlatformDataType, FW_kDataInterchangeStorage, FW_kImport);
- RegisterKind(ev, kJPEGOSType, kODPlatformFileType, FW_kAllStorage, FW_kImport);
- RegisterKind(ev, kJFIFOSType, kODPlatformDataType, FW_kDataInterchangeStorage, FW_kImport);
- RegisterKind(ev, kJFIFOSType, kODPlatformFileType, FW_kAllStorage, FW_kImport);
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::NewDocumentWindow
- //----------------------------------------------------------------------------------------
-
- FW_CWindow* CBitmapPart::NewDocumentWindow(Environment* ev)
- {
- FW_CRect bitmapRect;
- fBitmapContent->GetBitmap(ev).GetBitmapBounds(bitmapRect); // return in 72 dpi
- #ifdef FW_BUILD_MAC
- // Leave some room for the grow box
- bitmapRect.Inset(FW_IntToFixed(-16), FW_IntToFixed(-16));
- #endif
-
- FW_CRect screenBounds;
- ::FW_GetMainScreenBounds(screenBounds);
- screenBounds.Inset(FW_IntToFixed(3), FW_IntToFixed(3));
-
- return new FW_CWindow(ev,
- this,
- FW_CPart::fgViewAsFrameToken,
- fBitmapPresentation,
- bitmapRect.Size(),
- screenBounds.TopLeft(),
- FW_kDocumentWindow);
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::NewPartContent
- //----------------------------------------------------------------------------------------
- // ODF Method
-
- FW_CContent* CBitmapPart::NewPartContent(Environment* ev)
- {
- fBitmapContent = FW_NEW(CBitmapContent, (ev, this));
- return fBitmapContent;
- }
-
- #if FW_SUPPORTS_CYBERDOG
-
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::DoAdjustMenus
- // See "Cyberdog: Live Data" below in DoMenu.
- //----------------------------------------------------------------------------------------
-
- FW_Handled CBitmapPart::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
- {
- FW_UNUSED(isRoot);
- if (hasMenuFocus && fHelper) {
- menuBar->EnableCommand (ev, cReload, fHelper->GetCyberItem(ev) != kODNULL);
- menuBar->EnableAndCheckCommand (ev, cReloadFast, TRUE, fReloadContinuously);
- }
-
- return FW_kNotHandled;
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::DoAbout
- //----------------------------------------------------------------------------------------
-
- FW_Handled CBitmapPart::DoAbout(Environment* ev)
- {
- ::FW_About(ev, this, kAbout);
-
- return FW_kHandled;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::DoMenu
- //----------------------------------------------------------------------------------------
- // ODF method
-
- #if FW_SUPPORTS_CYBERDOG
-
- FW_Handled CBitmapPart::DoMenu(Environment* ev, const FW_CMenuEvent& theMenuEvent)
- {
- FW_Handled result = FW_kHandled;
-
- ODCommandID id = theMenuEvent.GetCommandID(ev);
- /*
- ----- Cyberdog: Live Data -----
-
- This is a cute feature which you may be able to put to real use.
- The Cyberdog Navigator has a "reload" command but it actually loads a new
- part (Cyberdog never calls you part to download data more than once). This
- Reload command will cause your part to open its CyberItem and download
- its data again (which may of course be updated data). A stock ticker
- part could make use of this for example.
-
- Unfortunately Bitmap flashes but that could be solved by offscreen
- buffering. And "Reload Continuously" would be improved by a Sleep delay.
- */
- if (id == cReload && fHelper) {
- fHelper->GetExtension(ev)->SetCyberItem (ev, fHelper->GetCyberItem(ev), kODNULL);
- }
- else if (id == cReloadFast && fHelper) {
- fReloadContinuously = !fReloadContinuously;
- }
- else if (id == kODCommandSaveACopy && fHelper) {
- /*
- ----- Cyberdog: Embedding in the Navigator (SaveAs) -----
-
- You would think that OpenDoc would handle SaveAs. It does, but it can
- only save another OD document. When we're doing browsing we frequently have
- pictures, etc, which we want to save as normal MacOS documents. Until
- OpenDoc supports multi-kind SaveAs, parts must do that themselves.
-
- Also, if we have a navigator part at the root, we might not want to save
- it. Therefore there are two situations where you need to use this SaveAs
- code: (1) Navigator is root part (2) You have multiple export kinds.
-
- In fact you **MUST** support SaveAs anyway if you want to be embeddable in
- the Navigator, because Cyberdog disables the OpenDoc Save mechanism.
-
- Basic question: Why would you implement your own Save As code instead of using
- OpenDocs? Because...
- (1) you want to export files as standard MacOS documents (not OD documents).
- (2) you don't want the navigator (browser) saved as the root part of the
- document.
-
- The new logic is to use the custom Save As code whenever we're in a
- "Cyberdog environment". That is...
- (1) navigator is the root part.
- (2) you are the root part but are in a Cyberdog draft.
-
- Note that being in a Cyberdog draft does not imply being in a "Cyberdog
- environment". For example, one could have ODFDraw, with a navigator embedded
- in it, and your part in the navigator. Your part would be in a Cyberdog
- draft but it would be important to use the default OD mechanism (since you
- want to save the whole document, not just your part).
-
- Note also that it's possible to be an embedded part in a part in the
- navigator. The logic doesn't handle this yet, but Cyberdog doesn't do
- embedded yet either, so it's not a problem which must be solved for R2.
- */
- CyberSession* session = GetCyberSession(ev);
- FW_Boolean inCyberDraft = session->IsInCyberDraft (ev, GetODPart(ev));
- FW_CFrame* probableFrame = GetLastActiveFrame(ev);
- FW_Boolean isRoot = probableFrame->IsRoot(ev);
- FW_Boolean isInRootNavigator = false;
- if (!isRoot) {
- FW_CAcquiredODPart nav = fHelper->AcquireContainingNavigator (ev);
- FW_Boolean isInNavigator = (nav != kODNULL);
- if (isInNavigator)
- isInRootNavigator = session->IsContainedInRootNavigatorPart (ev, probableFrame->GetODFrame(ev));
- }
- FW_Boolean handle = (isInRootNavigator || (isRoot && inCyberDraft));
- if (!handle)
- return FW_kNotHandled;
- // Get a default name
- FW_PFileSpecification whichFile (ev, "");
- short whichKind;
- FW_CString defaultName;
- if (fHelper && fHelper->GetCyberItem(ev)) {
- Str255 itemName;
- ScriptCode dummy;
- fHelper->GetCyberItem(ev)->GetStringProperty (ev, kCDFileName, itemName, &dummy);
- defaultName.ReplaceAll (itemName);
- }
- // Ask
- Boolean doIt = ::FW_AskSaveAs (kSaveAs, defaultName, whichFile, whichKind);
- if (doIt) {
- // Can't do OpenDoc or CyberItem yet
- if (whichKind == 1 || whichKind == 2) {
- FW_ASSERT (("Sorry, not yet implemented!", false));
- FW_Failure (FW_xUnknownError);
- }
- // Set up Picture file
- #ifdef FW_BUILD_MAC
- whichFile->MacSetTypeAndCreator (ev, 'PICT', 'JVWR');
- #endif
- // if (FW_FileSystem_IsValidFile (ev, whichFile))
- // FW_FileSystem_DeleteFile (ev, whichFile);
- FW_FileSystem_CreateFile (ev, whichFile, true);
- FW_CAccessPermission permission (FW_kWrite);
- FW_PFile file (ev, whichFile, permission, true);
- FW_PFileSink sink (ev, file);
- FW_CWritableStream stream (sink);
- // Write it out
- #ifdef FW_BUILD_MAC
- // PICT format is wierd. 512 bytes of nothing?
- char dummy [512];
- memset (dummy, 0, 512);
- sink->Write (ev, dummy, 512);
- #endif
- FW_CPicture picture = fBitmapContent->GetBitmap(ev).MacGetAsPicture();
- FW_PlatformPict platformPict = picture.GetPlatformPict();
- unsigned long pictSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)platformPict);
- FW_CAcquireLockedSystemHandle lockedHandle((FW_PlatformHandle)platformPict);
- stream.Write(lockedHandle.GetPointer(), pictSize);
- }
- }
- else
- result = FW_kNotHandled;
-
- return result;
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::UpdatePresentation
- //----------------------------------------------------------------------------------------
-
- void CBitmapPart::UpdatePresentation(Environment* ev)
- {
- // ----- Force all display frames to be redrawn
- fBitmapPresentation->Invalidate(ev);
-
- // ----- Force thumbnail to be recalculated -----
- fBitmapPresentation->UpdateViewAs(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::NewFrame
- //----------------------------------------------------------------------------------------
- // ODF Method
-
- FW_CFrame* CBitmapPart::NewFrame(Environment* ev,
- ODFrame* odFrame,
- FW_CPresentation* presentation,
- FW_Boolean fromStorage)
- {
- FW_UNUSED(fromStorage);
- FW_ASSERT(presentation == fBitmapPresentation);
-
- return FW_NEW(CBitmapFrame, (ev, odFrame, presentation, this, fBitmapContent));
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::AdjustFramesSize
- //----------------------------------------------------------------------------------------
- // Bitmap Part Method
-
- void CBitmapPart::AdjustFramesSize(Environment* ev)
- {
- FW_CPartFrameIterator ite(ev, this);
- for (CBitmapFrame* frame = (CBitmapFrame*)ite.First(ev); ite.IsNotComplete(ev); frame = (CBitmapFrame*)ite.Next(ev))
- {
- frame->AdjustFrameSize(ev);
- }
- }
-
- #if FW_SUPPORTS_CYBERDOG
-
- //----------------------------------------------------------------------------------------
- // CBitmapPart::LoadCyberItem
- //----------------------------------------------------------------------------------------
-
- void CBitmapPart::LoadCyberItem (Environment* ev, void* selfCPart)
- {
- /*
- ----- Cyberdog: Creating a Stream for Downloading -----
-
- This static method will be called automatically when a Cyberdog item is
- opened. It has been registered via SetLoadCyberItemThreadProcedure, which
- creates a new thread before calling this method. Since LoadCyberItem is
- running in its own thread, it can wait for data to arrive without holding
- up the user interface.
-
- */
- // Note this is a static method. "this" is passed in from Initialize
- CBitmapPart* self = (CBitmapPart*) selfCPart;
-
- CyberItem* item = self->fHelper->GetCyberItem(ev);
-
- // Support continuous downloads
- // We could do it by re-spawning our thread, but that causes problems
- // with the smart pointer (can't create a new thread while the original
- // one still exists). Therefore we'll just loop in the current thread.
- do {
-
- CyberStream* cStream = item->CreateCyberStream (ev);
- cStream->Open (ev);
- FW_PCyberSink sink (ev, cStream);
-
- FW_CBitmap b = ODF_JPEG_Read (ev, sink);
- self->fBitmapContent->SetBitmap (ev, b);
- self->fBitmapPresentation->Invalidate(ev);
-
- }
- while (self->fReloadContinuously);
- }
-
- #endif // FW_SUPPORTS_CYBERDOG
-
-