home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 11.0 KB | 392 lines | [TEXT/MPS ] |
- //==============================================================================
- //
- // File: FWSaveAs.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //==============================================================================
- //
- // Utility code for presenting a "Save As" dialog box.
- //
- // You need this when you need to export data and can choose between multiple
- // kinds. One might think that OpenDoc would handle it for you, but it doesn't
- // yet.
- //
- // Cyberdog disables the default OpenDoc saving code and requires each part to
- // implement SaveAs itself.
- //
- // Notes about the MacOS implementation:
- //
- // We have added a popup to the standard Save dialog. This requires us to
- // duplicate the system Save dialog, so you must localize it yourself. This is
- // unfortunate. A two-step Save interface (first ask format, then ask where)
- // would avoid this, and would perhaps be more useful for kinds like JPEG,
- // which require additional parameters. Or a hierarchical Save menu.
- //
-
- #include "FWFrameW.hpp"
-
- #ifndef FWSAVEAS_H
- #include "FWSaveAs.h"
- #endif
-
- #ifndef FWSAVEAS_K
- #include "FWSaveAs.k"
- #endif
-
- #ifndef FWENVDEF_H
- #include "FWEnvDef.h"
- #endif
-
- #ifndef FWKIND_H
- #include "FWKind.h"
- #endif
-
- #ifndef FWPART_H
- #include "FWPart.h"
- #endif
-
- #ifndef FWCFMRES_H
- #include "FWCFMRes.h"
- #endif
-
- #ifndef FWRESACC_H
- #include "FWResAcc.h"
- #endif
-
- #ifndef FWRESSIN_H
- #include "FWResSin.h"
- #endif
-
- #ifndef SOM_ODDispatcher_xh
- #include <Disptch.xh>
- #endif
-
- //
- // MacOS-specific Framework and Platform Declarations
- //
-
- #ifdef FW_BUILD_MAC
- # ifndef __DIALOGS__
- # include <Dialogs.h>
- # endif
- # ifndef SLLOCALE_H
- # include "SLLocale.h"
- # endif
- # ifndef FWSESION_H
- # include "FWSesion.h"
- # endif
- # ifndef __STANDARDFILE__
- # include "StandardFile.h"
- # endif
- #endif
-
-
- //------------------------------------------------------------------------------
- // Runtime Information
- //------------------------------------------------------------------------------
-
- #ifdef FW_BUILD_MAC
- #pragma segment FW_OS_SaveAs
- #endif
-
- //------------------------------------------------------------------------------
- // Utilities
- //------------------------------------------------------------------------------
- #pragma mark (Utilities)
-
- #ifdef FW_BUILD_MAC
-
- inline void FW_ExtractPascal (FW_CString s, Str255& ms)
- {
- short byteLength = s.GetByteLength();
- if (255 < byteLength) {
- s.Truncate (255);
- byteLength = 255;
- }
-
- s.ExportPascal (ms);
-
- // may need to remove 1/2 of a double-byte character
- FW_Locale locale;
- s.GetLocale (locale);
- if (byteLength && FW_CharIsDoubleByte ((char*)ms + 1, byteLength - 1, locale))
- ms[0]--;
- }
-
- #endif
-
- template <class T>
- inline void FW_DeleteAll (FW_TOrderedCollection<T>& list)
- {
- T* item = list.First();
- while (item) {
- list.Remove (item);
- delete item;
- item = list.First();
- }
- }
- //------------------------------------------------------------------------------
- // Prototypes
- //------------------------------------------------------------------------------
- #pragma mark (Prototypes)
-
- #ifdef FW_BUILD_MAC
-
- pascal short FW_PrivMacSaveAsDialogHook (short item, DialogPtr dialog, void* info_pointer);
- pascal Boolean FW_PrivMacSaveAsFilterProc (DialogPtr dialog, EventRecord* event, short* item, void* info_pointer);
-
- struct FW_SPrivMacSaveAsInfo {
- short item;
- const FW_TOrderedCollection<FW_CString>* items;
- ControlHandle popup;
- };
-
- #endif
-
- typedef pascal Boolean (*ModalFilterYDProcPtr)(
- DialogPtr theDialog, EventRecord *theEvent, short *itemHit, void *yourDataPtr);
-
- //------------------------------------------------------------------------------
- // Globals
- //------------------------------------------------------------------------------
- #pragma mark (Globals)
-
- #ifdef FW_BUILD_MAC
-
- RoutineDescriptor FW_gPrivMacSaveAsDialogHook =
- BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, FW_PrivMacSaveAsDialogHook);
-
- RoutineDescriptor FW_gPrivMacSaveAsFilterProc =
- BUILD_ROUTINE_DESCRIPTOR (uppModalFilterYDProcInfo, FW_PrivMacSaveAsFilterProc);
-
- const short FW_kPopupItemNumber = 13;
- const short FW_kSaveAsDialog = 29537;
- #endif
-
- //------------------------------------------------------------------------------
- // FW_AskSaveAs
- //------------------------------------------------------------------------------
-
- FW_Boolean FW_AskSaveAs (
- short resourceID /* in */,
- FW_CString defaultName /* in */,
- FW_PFileSpecification& whereToSave /* out */,
- short& kindChosen /* out */)
- {
- Boolean doSave = false;
- FW_CString prompt;
- short defaultKind = 1;
- FW_TOrderedCollection<FW_CString> items;
-
- FW_SOMEnvironment ev;
- FW_PSharedLibraryResourceFile partResources (ev);
- FW_PResource saveAsResource (ev, partResources, resourceID, FW_kSaveAsResourceType);
- FW_PResourceSink sink (ev, saveAsResource);
- FW_CReadableStream s (sink);
-
- s >> prompt;
-
- FW_TRY {
- // Now build a list of exportable kinds.
- short count;
- s >> count;
- for (int i = 1; i <= count; i++) {
- FW_CString name;
- s >> name;
- items.AddLast (FW_NEW (FW_CString, (name))); // XXX ugly
- }
-
- // Put up the dialog
- doSave = FW_AskSaveAsDynamic (items, defaultKind, prompt, defaultName,
- FW_kSaveAsDialog, whereToSave, kindChosen);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING() {
- // Clean up after above FW_NEW (FW_CString) if anything fails.
- FW_DeleteAll (items);
- FW_THROW_SAME ();
- }
- FW_CATCH_END
-
- FW_DeleteAll (items);
- return doSave;
- }
-
- //------------------------------------------------------------------------------
- // FW_AskSaveAsDynamic
- //------------------------------------------------------------------------------
-
- FW_Boolean FW_AskSaveAsDynamic (
- const FW_TOrderedCollection<FW_CString>& items /* in */,
- short defaultItem /* in */,
- FW_CString prompt /* in */,
- FW_CString defaultName /* in */,
- short resourceID /* in */,
- FW_PFileSpecification& whereToSave /* out */,
- short& kindChosen /* out */)
- {
- #ifdef FW_BUILD_MAC
- Str255 cpfPrompt;
- FW_ExtractPascal (prompt, cpfPrompt);
-
- Str255 cpfDefaultName;
- FW_ExtractPascal (defaultName, cpfDefaultName);
-
- StandardFileReply reply;
- Point where = { -1, -1 }; // auto-centered
-
- DlgHookYDUPP dlgHook = &FW_gPrivMacSaveAsDialogHook;
- ModalFilterYDUPP filterProc = &FW_gPrivMacSaveAsFilterProc;
- ActivationOrderListPtr activeList = nil;
- ActivateYDUPP activate = nil;
-
- FW_SPrivMacSaveAsInfo info;
- info.item = defaultItem;
- info.items = &items;
- info.popup = nil;
- void* yourDataPtr = &info;
-
- FW_SOMEnvironment ev;
- FW_PSharedLibraryResourceFile useResources (ev);
- ::CustomPutFile (cpfPrompt, cpfDefaultName, &reply, resourceID, where, dlgHook, filterProc, activeList, activate, yourDataPtr);
-
- if (reply.sfGood == false)
- return false;
-
- whereToSave = reply.sfFile;
- kindChosen = info.item;
- return true;
- #else
- # error unimplemented
- #endif
- }
-
- //------------------------------------------------------------------------------
- // FW_PrivMacSaveAsDialogHook
- //------------------------------------------------------------------------------
- // Handle clicks in the popup.
-
- #ifdef FW_BUILD_MAC
-
- pascal short FW_PrivMacSaveAsDialogHook (short item, DialogPtr dialog, void* info_pointer)
- {
-
- // Only filter the main dialog, not any nested dialogs.
- long windowKind = ::GetWRefCon (dialog);
- if (!windowKind == sfMainDialogRefCon)
- return item;
-
- FW_SPrivMacSaveAsInfo* info = (FW_SPrivMacSaveAsInfo*) info_pointer;
-
- if (item == sfHookFirstCall) {
- // Save popup reference
- Handle h;
- short dummy1;
- Rect dummy2;
- ::GetDialogItem (dialog, FW_kPopupItemNumber, &dummy1, &h, &dummy2);
- info->popup = (ControlHandle) h;
- // Insert items into the popup
- // XXX This does not compile with STRICT_CONTROLS defined. Unfortunately Maxwell
- // does not have interfaces for manipulating a control popup.
- PopupPrivateDataHandle controlData = (PopupPrivateDataHandle) (*info->popup)->contrlData;
- MenuHandle menu = (*controlData)->mHandle;
- FW_TOrderedCollectionIterator<FW_CString> strings (info->items);
- short index = 0;
- for (FW_CString* s = strings.First(); strings.IsNotComplete(); s = strings.Next()) {
- Str255 text;
- FW_ExtractPascal (*s, text);
- FW_ASSERT (text[0] != 0);
- ::AppendMenu (menu, "\pMozilla");
- index++;
- ::SetMenuItemText (menu, index, text);
- }
- // Set current value
- ::SetControlMaximum (info->popup, index);
- ::SetControlValue (info->popup, info->item);
- ::SetControlMinimum (info->popup, 1);
- }
- else if (item == sfHookLastCall)
- info->item = ::GetControlValue (info->popup);
-
- return item;
- }
-
- #endif
-
- //------------------------------------------------------------------------------
- // FW_PrivMacSaveAsFilterProc
- //------------------------------------------------------------------------------
- // Handle events in the dialog.
-
- /*
- Inside Macintosh - Files:
-
- The Standard File Package contains an internal filter function that performs
- some preliminary processing on each event it receives. If you provide a
- modal-dialog filter function, ModalDialog calls your filter function after
- it calls the internal Standard File Package filter function and before it
- sends the event to your dialog hook function.
-
- If your function returns a value of FALSE, ModalDialog processes the event
- through its own filters. If your function returns a value of TRUE, ModalDialog
- returns with no further action.
- */
-
- #ifdef FW_BUILD_MAC
-
- pascal Boolean FW_PrivMacSaveAsFilterProc (DialogPtr dialog, EventRecord* event, short* , void* )
- {
- // FW_SPrivMacSaveAsInfo* info = (FW_SPrivMacSaveAsInfo*) info_pointer;
-
- // Although we have no use for it, just to be safe always pass the event on to
- // the item handler.
- FW_Boolean passToDialogHook = true;
-
- // Let OpenDoc handle idle and update events for windows other than the dialog.
- FW_Boolean isDialogEvent = (DialogPtr) event->message == dialog;
- FW_Boolean passToOpenDoc = ((event->what == nullEvent) || (isDialogEvent && (event->what == updateEvt || event->what == activateEvt)));
-
- if (passToOpenDoc) {
- FW_TRY {
- FW_SOMEnvironment ev;
- FW_CSession::GetDispatcher(ev)->Dispatch (ev, event);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING() {
- }
- FW_CATCH_END
- }
-
- return !passToDialogHook;
- }
-
- #endif
-
- //------------------------------------------------------------------------------
- // Obsolete
- //------------------------------------------------------------------------------
-
- #if 0
- // Read ODType strings and make a list of user names by calling
- // the OD namespace utilities.
- const FW_TOrderedCollection<FW_CKind>* kinds = part->GetKinds();
- FW_TOrderedCollectionIterator<FW_CKind> eachKind (kinds);
- for (FW_CKind* kind = eachKind.First(); kind; kind = eachKind.Next()) {
- if (kind->IsExportEnabled(ev)) {
- ODType type = kind->GetType(ev);
- // Get the english-(or whatever-) language name for the type
- FW_CString name = type; // default if bindings are messed up
- ODIText* odName = kODNULL;
- if (::GetUserKindFromKind (FW_CSession::GetNameSpaceManager(ev), type, &odName))
- name = odName;
- items.AddLast (FW_NEW (FW_CString, (name))); // XXX ugly
- index++;
- if (kind->IsPreferredKind(ev))
- defaultKind = index;
- }
- }
- #endif
-
-