OpSlice Class Reference

The "Image Slice" menu item. More...

#include <slice.h>

Inheritance diagram for OpSlice:

OpMenuImport SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

void Do (OpDescriptor *)
 Exports the current document as slices defined by named selections.

Static Public Member Functions

static BOOL Init ()
 Declares the OpDescriptor.
static OpState GetState (String_256 *, OpDescriptor *)
 This item is always available, so long as a document is visible. Not really sure if I even need this!!!
static DocRect ScanLargeSliceBounds (const String_256 &Name)

Protected Member Functions

BOOL AddSlice (INT32 Ax, INT32 Ay, INT32 Cx, INT32 Cy, CList< CSlice *, CSlice * > *pMosaicList, String_256 SliceName)
 slice rect ABCD A---B | | D---C pMosaicList should start with one entry which is the whole drawing extent that is to be split up into sections. The passed in slice (AC) is added to the list of pieces which is a named user defined slice. Existing pieces that are occupy the same area are cut into smaller parts or absorbed.
BOOL InRect (CSlice *pRect, INT32 x, INT32 y)
 Tests if the point X,Y is in the rectangle defined by the slice.
BOOL Slice (CSlice *pRect, INT32 Ax, INT32 Ay, INT32 Bx, INT32 By, CList< CSlice *, CSlice * > *pMosaicList)
 Split the Slice pRect into smaller rectangles along the line AB.
BOOL CutsRect (CSlice *pRect, INT32 Ax, INT32 Ay, INT32 Bx, INT32 By)
 Tests to see if the line AB cuts the rectangle pRect.
BOOL SortSlices (CList< CSlice *, CSlice * > *pMosaicList, const DocRect &Bounds)
 Sorts the slices into order. Merges together suitable slices. Fills in colm & row positions, spans and width/heights for defining an HTML table. Gives names to nameless slices in the form r*c*.
BOOL ExportImageSliceHTML (CList< CSlice *, CSlice * > *pMosaicList, const String_256 &HTMLFile, INT32 FileNumber=1)
 Creates an HTML file with a table that re-weaves the sliced images back together Also if rollovers have been defined they are also incorperated.
BOOL ExportSliceGraphic (CSlice *pSlice, BitmapExportOptions *pExportOptions, const String_256 &GraphicFileName)
 Generates a graphic of a section of the whole image defined by the rectangular area of the slice. Params: pSlice - the slice to export contains area rect and name.
BOOL SaveFileDlg ()
 Brings up the save dlg to ask the user where to save the html and the slices too. Also has the filter selection to choose from when picking the default slice. Sets the path location, name and graphic type into the variable m_PathName.
INT32 TidyMosaicList (CList< CSlice *, CSlice * > *pMosaicList)
 Deletes all the slices in the list now that we are done with them. So there will be no memory leeks.
void UpdateSliceFileExts (CList< CSlice *, CSlice * > *pMosaicList)
 Changes all non set file types to be the type the user picks from the file dlg.
void NudgeSliceIfClose (INT32 &Ax, INT32 &Ay, INT32 &Cx, INT32 &Cy, CList< CSlice *, CSlice * > *pMosaicList)
 Moves the new slice over a bit if it just overlaps with an existing slice due to the pixel infation. It does this by adjusting the AC rectangle passed in.
void RemoveIlligalFileAndJavaChars (String_256 &Str)
 Replaces any illigal chars in the Str as far as filenames and use as javascript variables for use in rollovers is concerned.
String_256 TurnUnderScoreIntoSpace (const String_256 &StartStr)
void PixelAlignedInflate (DocRect *r)
 Infates a DocRect to the nearest pixel aligned boundary.
void MarkEmptySlices (CList< CSlice *, CSlice * > *pMosaicList, DocRect &SelRect, BitmapExportOptions *pExportOptions)
 What it is meant to do is check if the drawing has anything that is visible within this slice. So if there is nothing visible don't bother generating a graphic for it. Any empty slices are set as empty in the list of slices. Method used is to render the image to be exported as a 32bit graphic and then check the alpha channel for anything non-transparent. Param pMoasicList - List of the slices SelRect - The rect of the image being exported Returns - Errors Not putting a graphic into the HTML table may screw up the sizing of cells in the table if it was relying on this cell to get the size information. So instead I re-use the shim graphic expanded to that size (see the ExportHTML fn).
void ScanTextStorySliceBounds (const String_256 &Name, DocRect &Bounds)
CSliceGetButtonNumber (CList< CSlice *, CSlice * > *pMosaicList, INT32 buttonno)
BOOL ScanForRolloverStates (CList< CSlice *, CSlice * > *pMosaicList)
 Sets the m_RolloverState member variable by scanning the layers and finding out what specail named layers exist for the creation of rollovers.
BOOL ExportRollOverSlice (CSlice *pSlice, BitmapExportOptions *pExportOptions)
 Exports all the rollover states of this given slice if they are defined.
void ShowRolloverLayer (INT32 ShowLayer)
 Shows the layer number passed to it and hides the other of the rollover layers. Pass it DEFAULT, MOUSE, CLICKED, SELECTED, ORIGINAL_LAYERS or ALL_LAYERS.
BOOL URLScan (String_256 *pLinkName, CList< CSlice *, CSlice * > *pMosaicList)
 Scans through the tree looking for URL tags. If it finds one it looks for a set name on the same node. If it finds a set name it scans the Mosaic list for the button with that set name and records the URL as the link name for that button number Param pMoasicList - List of the slices pLinkName - The dynamic array holding the URLs for each button Returns TRUE if it ran ok.
void FailledToExportHTML (const String_256 &file)
 Puts up an error msg saying that it could export the HTML and marks it as unexported Param file - The file it failled to export Returns.

Static Protected Member Functions

static BYTE * LoadFileIntoMemory (String_256 FileName, DWORD &Size)
 Creates a copy of the file in memory and says how big it is Param Filename - The file to open Size - Fills in this param with the size of the memory object created Returns a ptr to the memory, or NULL if it failled.
static BYTE * FindNextOccuranceOf (BYTE *pSearch, BYTE *pFrom)
 Finds the next occurance of a string in the other large 'string'. Pass in lowercase and it will match with uppercase letters Param pSearch - The shorter string being searched for pFrom - The larger string to find it in Returns a ptr to the memory where the search string was located nearest to the starting point, or NULL if it wasn't found.
static BYTE * FindPreviousChar (char Search, BYTE *pFrom, BYTE *pLimit)
static void WriteText (ofstream &f, BYTE *pData, INT32 NoOfBytes)
 There appeared to be a slight problem when using the write function to output text to the ofstream that contained chars 10 & 13. This function neatens this up cutting out 10,13 & 0 and putting a nice
in the right places. Param f - The output stream pData - the string to output NoOfBytes - Number of bytes to send to the stream Returns.

Protected Attributes

PathName m_PathName
String_256 m_HTMLext
INT32 m_lRed
INT32 m_lGreen
INT32 m_lBlue
String_256 m_ErrorStr
BOOL m_UsedShimGraphic
BOOL m_UsesDesignNotes
String_256m_pLinkName
RolloverState m_RolloverState [4]
BOOL m_FoundRolloverStates
INT32 m_NumberOfButtons
BOOL m_ExportedHTMLOK
BOOL m_InjectHTML

Detailed Description

The "Image Slice" menu item.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/99
See also:

Definition at line 194 of file slice.h.


Member Function Documentation

BOOL OpSlice::AddSlice INT32  Ax,
INT32  Ay,
INT32  Cx,
INT32  Cy,
CList< CSlice *, CSlice * > *  pMosaicList,
String_256  SliceName
[protected]
 

slice rect ABCD A---B | | D---C pMosaicList should start with one entry which is the whole drawing extent that is to be split up into sections. The passed in slice (AC) is added to the list of pieces which is a named user defined slice. Existing pieces that are occupy the same area are cut into smaller parts or absorbed.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/7/99
Params: Axy, Cxy defines the new slice pMosaic is this list of the slices SliceName is the name of the new slice

Returns:
TRUE if it worked - FALSE if something failled

Definition at line 983 of file slice.cpp.

00984 {
00985     // ignore empty slices as we could hardly export them
00986     // but since slices containing nothing could exist we should cater
00987     // for the possibility
00988     if (Ax == Cx || Ay == Cy) return TRUE;
00989 
00990     // if the inflate to pixel aligned rect has swapped over two named slices
00991     // set them to being on the same boundry
00992     NudgeSliceIfClose(Ax, Ay, Cx, Cy, pMosaicList);
00993 
00994     BOOL ok = TRUE;
00995     POSITION pos = pMosaicList->GetHeadPosition();
00996 
00997     while (pos)
00998     {
00999         POSITION thispos = pos;
01000         CSlice * pRect = pMosaicList->GetNext(pos);
01001         BOOL RemoveMe = TRUE;
01002         
01003         if (Ax == pRect->left && Cx == pRect->right && Ay == pRect->top && Cy == pRect->bottom)
01004         {
01005             // remove existing identical slices
01006             // keep the name if it has one and the replacement doesn't.
01007             if (!pRect->name.IsEmpty())
01008             {
01009                 TRACE( _T("Identically named slices\n"));
01010                 if (SliceName.IsEmpty())
01011                     SliceName = pRect->name;
01012             }
01013         }
01014         else
01015         if (InRect(pRect, Ax, Ay)) // A in rect
01016             ok = Slice (pRect, Ax, Ay, Cx, Ay, pMosaicList); // slice AB
01017         else
01018         if (InRect(pRect, Cx, Ay)) // B in rect
01019             ok = Slice (pRect, Ax, Ay, Cx, Ay, pMosaicList); // slice AB
01020         else
01021         if (CutsRect(pRect, Ax, Ay, Cx, Ay)) // cuts AB
01022             ok = Slice (pRect, Ax, Ay, Cx, Ay, pMosaicList); // slice AB
01023         else
01024         if (InRect(pRect, Cx, Cy)) // C in rect
01025             ok = Slice (pRect, Cx, Ay, Cx, Cy, pMosaicList); // slice BC
01026         else
01027         if (CutsRect(pRect, Cx, Ay, Cx, Cy)) // cuts BC
01028             ok = Slice (pRect, Cx, Ay, Cx, Cy, pMosaicList); // slice BC
01029         else
01030         if (InRect(pRect, Ax, Cy)) // D in rect
01031             ok = Slice (pRect, Ax, Ay, Ax, Cy, pMosaicList); // slice AD
01032         else
01033         if (CutsRect(pRect, Ax, Ay, Ax, Cy)) // cuts AD
01034             ok = Slice (pRect, Ax, Ay, Ax, Cy, pMosaicList); // slice AD
01035         else
01036         if (CutsRect(pRect, Ax, Cy, Cx, Cy)) // cuts DC
01037             ok = Slice (pRect, Ax, Cy, Cx, Cy, pMosaicList); // slice DC
01038         else
01039         if (pRect->left >= Ax && pRect->right <= Cx && pRect->top >= Ay && pRect->bottom <= Cy) // rect in ABCD
01040             //remove rect from list
01041         {
01042             TRACE( _T("remove sub rect\n"));
01043             // NB doing nothing will result in it being removed
01044         }
01045         else // this piece doesn't interact with the slice at all
01046             RemoveMe = FALSE; // so don't let it be taken from us
01047 
01048         if (!ok)
01049             return FALSE; // an error occurred
01050         
01051         pos = thispos;
01052         // reget the next item to check that we haven't extended the list
01053         pRect = pMosaicList->GetNext(pos);
01054 
01055         if (RemoveMe)
01056         {
01057             pMosaicList->RemoveAt(thispos);
01058             delete pRect;
01059         }
01060     }
01061 
01062     // add the slice passed in
01063     // remember to give it the users individually selected graphic type
01064     // which isn't yet implimented
01065     RemoveIlligalFileAndJavaChars(SliceName);
01066     pMosaicList->AddHead(new CSlice(Ax, Ay, Cx, Cy, SliceName, m_PathName.GetType(), TRUE));
01067 
01068     return ok;
01069 }

BOOL OpSlice::CutsRect CSlice pRect,
INT32  Ax,
INT32  Ay,
INT32  Bx,
INT32  By
[protected]
 

Tests to see if the line AB cuts the rectangle pRect.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/7/99
Returns:
TRUE if it does cut

Definition at line 1139 of file slice.cpp.

01140 {
01141     if (Ax == Bx) // Vert cut
01142     {
01143         // top & bottom outside rect
01144         // while the vertical line cuts through the rect
01145         if (Ay <= pRect->top && By >= pRect->bottom
01146             && Ax < pRect->right && Ax > pRect->left)
01147             return TRUE;
01148     }
01149     else
01150     if (Ay == By) // Horiz cut
01151     {
01152         // left & right outside rect
01153         // while the horizontal line cuts through the rect
01154         if (Ax <= pRect->left && Bx >= pRect->right
01155             && Ay < pRect->bottom && Ay > pRect->top)
01156             return TRUE;
01157     }
01158     
01159     return FALSE;
01160 }

void OpSlice::Do OpDescriptor  )  [virtual]
 

Exports the current document as slices defined by named selections.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/99
Returns:
Errors: -

Reimplemented from OpMenuImport.

Definition at line 285 of file slice.cpp.

00286 {
00287     // there needs to be a spread
00288     Spread* pSelSpread = Document::GetSelectedSpread();
00289     if (pSelSpread == NULL)
00290         return;
00291 
00292     //  Let's set a variable in BmapPrevDlg which will be used to determine
00293     //  which of the tab controls should be enabled or disabled.
00294     BmapPrevDlg::m_bSlicingImage = TRUE;
00295 
00296     m_ErrorStr = "none";
00297     m_HTMLext = "htm";
00298 
00299     m_NumberOfButtons = 0;
00300 
00301     // init the export path - which probably isn't needed
00302     // but better safe than sorry etc...
00303     // set to .non so that any slices that are defined from this can be
00304     // found and redefined later. see UpdateSliceFileExts() - sjk
00305     m_PathName.SetPathName("c:\\untitled.non");
00306 
00307     m_InjectHTML = FALSE; // don't inject without thinking about it - you know it makes sense!
00308 
00309     m_ExportedHTMLOK = TRUE; // asumes the best :-)
00310 
00311     // start a slow job
00312     Progress LongJob;
00313     LongJob.Start();
00314 
00315     // test if we use design notes
00316     m_UsesDesignNotes = UsesDesignNotes();
00317 
00318     // calculate the background colour
00319     DocColour dcol = Page::GetPageColour();
00320     m_lRed = m_lGreen = m_lBlue = 255;
00321 
00322     BOOL HasBitmapBackground = FALSE;
00323 
00324     Layer * pLayer = pSelSpread->FindFirstPageBackgroundLayer();
00325     if (pLayer)
00326     {
00327         Node * pNode = SliceHelper::FindNextOfClass(pLayer, pLayer, CC_RUNTIME_CLASS(AttrFlatColourFill));
00328         if (pNode)
00329             dcol = *(((AttrFlatFill *)pNode)->GetStartColour());
00330         else
00331         {
00332             if (SliceHelper::FindNextOfClass(pLayer, pLayer, CC_RUNTIME_CLASS(AttrBitmapColourFill)))
00333                 HasBitmapBackground = TRUE;
00334         }
00335     }
00336 
00337     dcol.GetRGBValue(&m_lRed, &m_lGreen, &m_lBlue);
00338 
00339     
00340     // calculate the bounds of the entire image
00341     // init the mosaic list which stores all the parts of the image
00342 
00343     CList <CSlice *, CSlice *> MosaicList;
00344     MosaicList.RemoveAll();
00345 
00346     // the bounds of the drawing
00347     DocRect SpreadBounds = BaseBitmapFilter::GetSizeOfDrawing(pSelSpread); // returns in spread co-ords ignoring silly layers
00348     
00349     // get the selection
00350     Range Sel(*(GetApplication()->FindSelection()));
00351 
00352     // set the range flags so it includes shadow and bevel manager nodes
00353     RangeControl rg = Sel.GetRangeControlFlags();
00354     rg.PromoteToParent = TRUE;
00355     Sel.Range::SetRangeControl(rg);
00356     BOOL UseWholeDrawing = TRUE;
00357     
00358     // get the size of the selection
00359     // if there is a selection use this as the area to export rather than the drawing area
00360     // which we will use if there is no selection made
00361     if (!Sel.IsEmpty())
00362     {
00363         SpreadBounds = Sel.GetBoundingRect();
00364         UseWholeDrawing = FALSE;
00365     }
00366 
00367     PixelAlignedInflate(&SpreadBounds); // pixel align the starting rect
00368 
00369     // find the defined slices
00370     NameGallery* pNameGallery = NameGallery::Instance();
00371     SGUsedNames* pNames = pNameGallery?NameGallery->GetUsedNames():NULL;
00372 
00373     if (!pNames)
00374     {
00375         InformWarning( _R(IDS_NOSLICES) );
00376         //  Reset:
00377         BmapPrevDlg::m_bSlicingImage = FALSE;
00378         return;
00379     }
00380 
00381     // make sure we are dealing with the most uptodate information
00382     pNameGallery->FastUpdateNamedSetSizes();
00383 
00384     // for each defined slice in the name gallery
00385     BOOL NoProblems = TRUE;
00386     BOOL AddedASlice = FALSE;
00387     BOOL OutsideSpread = FALSE;
00388 
00389     INT32 Attempts = 0; // first try with the large rects then if that fails try the smaller ones
00390     String_256 strName(TEXT("Empty"));
00391     String_256 Slice1ErrorStr = "";
00392     String_256 Slice2ErrorStr = "";
00393     INT32 SlicesDefinedInDrawing = 0;
00394 
00395     do
00396     {
00397         NoProblems = TRUE;
00398         AddedASlice = FALSE;
00399         OutsideSpread = FALSE;
00400         SlicesDefinedInDrawing = 0;
00401 
00402         // the original mosaic piece is the whole bounded image
00403         // which will be broken up
00404         TidyMosaicList(&MosaicList);
00405         MosaicList.AddHead(new CSlice(SpreadBounds.lox, SpreadBounds.loy, SpreadBounds.hix, SpreadBounds.hiy));
00406 
00407         SGNameItem* pItem = (SGNameItem*) pNames->GetChild();
00408 
00409         while (pItem != 0 && NoProblems)
00410         {
00411             // is the tick set in the name gallery to use this slice?
00412             BOOL UseThisSlice = TRUE;
00413             NamedTickboxProp * pSliceTick = (NamedTickboxProp *) pItem->GetProperty(1); // 1 is slices
00414             if (pSliceTick)
00415             {
00416                 UseThisSlice = pSliceTick->GetState();
00417                 if (UseThisSlice)
00418                     SlicesDefinedInDrawing++;
00419             }
00420 
00421             // dont use an unselected slice if it is not the whole drawing being exported
00422             if (!UseWholeDrawing && pItem->IsNoneSelected())
00423                 UseThisSlice = FALSE;
00424 
00425             if (UseThisSlice)
00426             {
00427                 DocRect r;
00428                 r = pItem->GetSetBounds();          // (returned in spread co-ords)
00429 
00430                 pItem->GetNameText(&strName);
00431 
00432                 // expand for actual text story visible size
00433                 ScanTextStorySliceBounds(strName, r);
00434 
00435                 if (Attempts == 0)
00436                 {
00437                     DocRect rLarge = ScanLargeSliceBounds(strName);
00438                     r = r.Union(rLarge); // use the large rects
00439                 }
00440 
00441                 // r must be in the spread bounds
00442                 // if it is outside the bounds it should be ignored
00443                 PixelAlignedInflate(&r);        // pixel align the slice
00444 
00445                 // trim anything that just strays over the bounds
00446                 r = r.Intersection(SpreadBounds);
00447 
00448                 // cut the existing mosaic pieces by the edges of this new piece
00449                 // which of course creates even more pieces
00450                 if (r.IsValid() && r.Height() > 0 && r.Width() > 0)
00451                 {
00452                     NoProblems = NoProblems && AddSlice(r.lox, r.loy, r.hix, r.hiy, &MosaicList, strName);
00453                     AddedASlice = TRUE;
00454                 }
00455                 else
00456                 {
00457                     TRACEUSER( "SimonK", _T("Slice outside bounds of the drawing!!!\n"));
00458                 }
00459             }
00460 
00461             if (NoProblems) pItem = (SGNameItem*) pItem->GetNext();
00462         }
00463 
00464         Attempts++;
00465         if (!NoProblems)
00466         {
00467             Slice1ErrorStr = m_ErrorStr;
00468             Slice2ErrorStr = strName;
00469         }
00470 
00471     } while (!NoProblems && Attempts < 2); // try twice , first with the max size slices, then with the smaller slices
00472 
00473 /* Dont ask the question Asumme that the user will choose to have the shadows cut if they do overlap (sjk 20/12/00)
00474     if (Attempts == 2 && NoProblems && AddedASlice)
00475     {   // worked with the smaller rects but not with the larger ones
00476 
00477         // I need to force this message to reappear again if they click 'Help' - Matt 10/11/2000
00478         INT32 result = 3;
00479         while (result == 3)
00480         {
00481             result = AskQuestion(_R(IDS_SLICES_MAY_OVERLAP), _R(IDS_YES), _R(IDS_NO), _R(IDS_HELP));
00482             if (result == 2)
00483             {
00484                 NoProblems = FALSE; // it is a problem if you say it is
00485                 m_ErrorStr = Slice1ErrorStr; // restore the shapes that were causing problems for the first case
00486                 strName = Slice2ErrorStr;
00487             }
00488             if (result == 3)
00489             {
00490                 HelpUserTopic(_R(IDH_Alert_Exclude_peripheral_elements));
00491             }
00492         }
00493     }
00494 */
00495     POSITION Test = NULL;
00496 
00497     if (NoProblems && AddedASlice) 
00498     {
00499         // sort the mosaic using SortSlices()
00500         // it also merges small bits back together if it can
00501         SortSlices(&MosaicList, SpreadBounds);
00502 
00503         // mark which states exist
00504         m_FoundRolloverStates = ScanForRolloverStates(&MosaicList);
00505 
00506         BOOL ReplaceFiles = TRUE;
00507         BOOL FilesOverwriten = FALSE;
00508         do // loop to ask where to save to which may be asked more than once if they dont want
00509             // to overwrite files
00510         {
00511 
00512             // ask where to save the files
00513             // and find out which slice export type to use
00514             if (!SaveFileDlg())
00515             {
00516                 // tidy up and leave if cancelled
00517                 TidyMosaicList(&MosaicList);
00518                 Error::ClearError();
00519                 //  Reset:
00520                 BmapPrevDlg::m_bSlicingImage = FALSE;
00521                 return;
00522             }
00523 
00524 
00525             // cope with things being .html, which the BmapPrevDlg doesn't set correctly as its not 8.3
00526             String_256 temp = m_PathName.GetFileName(FALSE);
00527             INT32 dot = temp.FindNextChar(TCHAR ('.'));
00528             if (dot > 0)
00529             {
00530                 String_256 end = "";
00531                 temp.Split(&temp, &end, dot, FALSE);
00532                 if (end.CompareTo(".html", FALSE) == 0)
00533                 {
00534                     m_HTMLext = "html";
00535                     m_PathName.SetFileName(temp);
00536                 }
00537             }
00538 
00539             CString ClickedFile(temp);
00540             ClickedFile += "." + m_HTMLext;
00541 
00542             ReplaceFiles = FileExists(ClickedFile);
00543             FilesOverwriten = FALSE;
00544 
00545             if (!ReplaceFiles)
00546             {
00547                 // test if these names we are creating are already in existance
00548                 Test = MosaicList.GetHeadPosition();
00549                 while (Test && !FilesOverwriten)
00550                 {
00551                     CSlice* pTestSlice = MosaicList.GetNext(Test);
00552                     CString TestName (pTestSlice->name);
00553 
00554                     // we dont know exactly what file type for each element will be
00555                     // but it is best to warn the user that they may be overwriting their files
00556                     FilesOverwriten = FileExists(TestName + ".gif");
00557                     if (!FilesOverwriten) FilesOverwriten = FileExists(TestName + ".jpg");
00558                     if (!FilesOverwriten) FilesOverwriten = FileExists(TestName + ".jpeg");
00559                     if (!FilesOverwriten) FilesOverwriten = FileExists(TestName + ".png");
00560                     if (!FilesOverwriten) FilesOverwriten = FileExists(TestName + ".bmp");
00561                 }
00562             }
00563 
00564             if (FilesOverwriten && !ReplaceFiles)
00565             {
00566                 // ask the user "This folder contains a graphic file with a conflicting name.
00567                 // Do you want to overwrite any conflicting files in this folder?"
00568                 if (InformWarning(_R(IDS_CONFLICTING_SLICE_FILENAMES), _R(IDS_OVERWRITE_GRAPHIC), _R(IDS_SAVE_ELSEWHERE)) == 1)
00569                     ReplaceFiles = TRUE;
00570             }
00571 
00572         } while (FilesOverwriten && !ReplaceFiles); // end of overwrite loop
00573 
00574 
00575         // The preview dlg wants to know the path of the image being
00576         // exported so give it the m_PathName
00577         BmapPrevDlg::m_pthExport = m_PathName;
00578 
00579         // set up the export options
00580         BitmapExportOptions * pExportOptions = NULL;
00581         BOOL ok = TRUE;
00582 
00583         ShowRolloverLayer(ALL_LAYERS);
00584 
00585         // WARNING SetUpExportOptions() actually 'new's the ExportOptions
00586         // so you will have to delete them or pass them to a function
00587         // that deletes them for you
00588         String_256 strExt = m_PathName.GetType();
00589         strExt.toLower();
00590         if (strExt.CompareTo("jpg") == 0)
00591         {
00592             JPEGExportFilter f;
00593             ok = f.SetUpExportOptions(&pExportOptions);
00594         }
00595         else
00596         if (strExt.CompareTo("bmp") == 0)
00597         {
00598             BMPFilter f;
00599             ok = f.SetUpExportOptions(&pExportOptions);
00600         }
00601         else
00602         if (strExt.CompareTo("png") == 0)
00603         {
00604             PNGFilter f;
00605             ok = f.SetUpExportOptions(&pExportOptions);
00606         }
00607         else
00608         //if (strExt == "gif")
00609         {
00610             TI_GIFFilter f;
00611             ok = f.SetUpExportOptions(&pExportOptions);
00612         }
00613 
00614         // the export options may have changed types
00615         // so ask the export dlg for the actual export options
00616         pExportOptions = BmapPrevDlg::m_pExportOptions;
00617         // take responsibility for the export options away from the bmp preview dlg
00618         BmapPrevDlg::m_pExportOptions = 0;
00619 
00620         // Cancelled from the export options dlg
00621         if (!ok)
00622         {
00623             if (pExportOptions)
00624             {
00625                 delete pExportOptions;
00626             }
00627             // tidy up and leave
00628             TidyMosaicList(&MosaicList);
00629             Error::ClearError();
00630             //  Reset:
00631             BmapPrevDlg::m_bSlicingImage = FALSE;
00632             return;
00633         }
00634 
00635         // read the m_PathName back since
00636         // setting up the export options could
00637         // have changed this value
00638         m_PathName = BmapPrevDlg::m_pthExport;
00639 
00640 
00641         // clear the screen by calling an idle
00642         (DocView::GetSelected())->ForceRedraw();
00643         GetApplication()->OnIdle(TRUE);             // Phil 2/7/2004 YUK! What's wrong with ServiceRendering?
00644 
00645         // change the non-user defined slices to use the graphic type
00646         // just picked by the user in the SaveFileDlg
00647         UpdateSliceFileExts(&MosaicList);
00648 
00649         // mark any "empty" slices in the list
00650         // but not if we have a background bitmap
00651         if (!HasBitmapBackground)
00652             MarkEmptySlices(&MosaicList, SpreadBounds, pExportOptions);
00653 
00654         // export each section of the mosaic as a seperate graphic
00655         Test = MosaicList.GetHeadPosition();
00656         while (Test)
00657         {
00658             CSlice* pTestSlice = MosaicList.GetNext(Test);
00659 
00660             if (m_FoundRolloverStates && pTestSlice->IsNamedSlice)
00661                 // export this slice as a rollover
00662                 ExportRollOverSlice(pTestSlice, pExportOptions);
00663             else
00664                 // do a normal slice
00665             {
00666                 // only export the graphic for a none-empty slice
00667                 if (!pTestSlice->IsEmpty)
00668                     ExportSliceGraphic(pTestSlice, pExportOptions, pTestSlice->name);
00669             }
00670 
00671             // This function calls DoExportWithParams() which used to
00672             // delete the export options (and not zero the pointer - tusk!)
00673             // Behaviour now changed by using DontLetFilterDeleteMyPointer()
00674             // so we can keep using the same export options, but of course we
00675             // must then delete them ourselves.
00676         }
00677 
00678         // tidy up our generated export options
00679         if (pExportOptions != 0)
00680         {
00681             delete pExportOptions;
00682             pExportOptions = 0;
00683         }
00684 
00685         // And clean up the image export options in the bitmap dialogue.
00686 //      BmapPrevDlg::CancelTransparency ();
00687 
00688         // export the HTML to display the mosaic put back together
00689         // the name is that typed in but with the htm extension
00690 
00691         // build up the list of link names with each button
00692         // rather than just going on adding a number to the file
00693         // users want to not have to edit HTML, do it all for them!
00694         m_UsedShimGraphic = FALSE;
00695         PathName HTMLPath = m_PathName;
00696         HTMLPath.SetType(m_HTMLext);
00697         m_pLinkName = NULL;
00698         INT32 i = 0;
00699         String_256 LaunchString = HTMLPath.GetFileName();
00700 
00701         INT32 LinkEntries = max (m_NumberOfButtons, 1);
00702         m_pLinkName = new String_256[LinkEntries];
00703 
00704         if (m_pLinkName)
00705         {
00706             m_pLinkName[0] = HTMLPath.GetPath();
00707 
00708             INT32 FileNumber = 0;
00709             // fill the link names with default names if there are no URLs found
00710             for (i = 0; i < m_NumberOfButtons; i++)
00711             {
00712                 m_pLinkName[i] = m_PathName.GetFileName(FALSE);
00713 
00714                 CSlice * pTestSlice = GetButtonNumber (&MosaicList, i+1);
00715                 if (pTestSlice && pTestSlice->ExistsOnLayerState[SELECTED])
00716                 {
00717                     FileNumber++;
00718 
00719                     if (m_FoundRolloverStates && m_RolloverState[SELECTED].Exists && FileNumber > 1)
00720                     {
00721                         String_256 NewName;
00722                         NewName.MakeMsg(_R(IDS_HTML_NAME_SPEC), (LPCSTR) m_PathName.GetFileName(FALSE), FileNumber);
00723                         m_pLinkName[i] = NewName;
00724                     }
00725                 }
00726 
00727                 m_pLinkName[i] += ".";
00728                 m_pLinkName[i] += m_HTMLext;
00729             }
00730 
00731             // scan the tree for any URLs used associated with the buttons in the Mosaic list
00732             // this will overwrite the defaults already set in m_pLinkName
00733             URLScan(m_pLinkName, &MosaicList);
00734 
00735             FileNumber = 0;
00736 
00737             // export each HTML file required
00738             if (m_RolloverState[SELECTED].Exists)
00739                 for (i = 0; i < LinkEntries; i++)
00740                 {
00741                     String_256 NewName = m_pLinkName[i];
00742                     String_256 Temp = "";
00743 
00744                     // dont try to create a file http://www.stuff...
00745                     NewName.Left(&Temp,5);
00746                     BOOL isURL = (Temp.CompareTo("http:", FALSE) == 0);
00747                     if (!isURL)
00748                     {
00749                         NewName.Right(&Temp,1);
00750                         isURL = (Temp.CompareTo("/") == 0);
00751                     }
00752 
00753                     CSlice * pTestSlice = GetButtonNumber (&MosaicList, i+1);
00754                     if (pTestSlice && pTestSlice->ExistsOnLayerState[SELECTED])
00755                     {
00756                         FileNumber++;
00757 
00758                         if (isURL)
00759                         {
00760                             NewName.MakeMsg(_R(IDS_HTML_NAME_SPEC), (LPCSTR) m_PathName.GetFileName(FALSE), FileNumber);
00761                             NewName += ".";
00762                             NewName += m_HTMLext;
00763                         }
00764 
00765                         HTMLPath.SetPathName(NewName);
00766 
00767                         if (!ExportImageSliceHTML(&MosaicList, HTMLPath.GetPath(), i+1))
00768                             FailledToExportHTML (HTMLPath.GetPath());
00769 
00770                         // set file to launch if changed by the URL
00771                         if (FileNumber == 1)
00772                         {
00773                             LaunchString = HTMLPath.GetFileName();
00774                         }
00775                     }
00776 
00777                 }
00778             else
00779                 if (!ExportImageSliceHTML(&MosaicList, HTMLPath.GetPath()))
00780                     FailledToExportHTML (HTMLPath.GetPath());
00781 
00782             delete [] m_pLinkName;
00783             m_pLinkName = NULL;
00784         }
00785 
00786         // Export out the required shim
00787         if (m_UsedShimGraphic)
00788         {
00789             // also needs shim.gif exported
00790             // set up the path of where to save it
00791             PathName ShimPath = m_PathName;
00792 
00793             ShimPath.SetFileName("shim");
00794             ShimPath.SetType("gif");
00795 
00796             CCDiskFile File;
00797             if(File.open(ShimPath.GetPath(), (ios::in | ios::out | ios::binary)))
00798             {
00799                 BYTE buf[] =   {0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00,
00800                                 0x01, 0x00, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
00801                                 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x01, 0x14,
00802                                 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00,
00803                                 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44,
00804                                 0x01, 0x00, 0x3B, 0x00  };
00805 
00806                 // make the shim of the correct colour
00807                 buf[13] = (BYTE) m_lRed;
00808                 buf[14] = (BYTE) m_lGreen;
00809                 buf[15] = (BYTE) m_lBlue;
00810 
00811                 // write the file
00812                 File.write((BYTE *)buf, 44);
00813                 File.close();
00814             }
00815         }
00816         
00817         // display the export HTML now?
00818         if (m_ExportedHTMLOK && AskQuestion(_R(IDS_SHOW_HTML_NOW), _R(IDS_YES), _R(IDS_NO)) == 1)
00819         {
00820             // shell execute the browser
00821             HINSTANCE hChild = ShellExecute(HWND_DESKTOP, "open", LaunchString, NULL, NULL ,SW_SHOW);
00822 
00823             // If the function (ShellExecute()) fails, then an error value that is less than or equal to 32 is returned. 
00824             INT32 Result = (INT32)hChild;
00825             // problems?
00826             if (Result <= 32)
00827             {
00828                 InformWarning(_R(IDS_NO_BROWSER));
00829             }
00830         }
00831     
00832     }
00833     else if (!AddedASlice) // user forgot to define any slices
00834     {
00835         if (SlicesDefinedInDrawing == 0)
00836             InformWarning( _R(IDS_NOSLICES) );
00837         else
00838             InformWarning( _R(IDS_NOSLICES_SELECTED) );
00839     }
00840     else // some error occured such as intersecting named slices
00841     {
00842         if (OutsideSpread)
00843         {
00844             // An invisible slice is outside the bounds of the rendered spread
00845             InformWarning(_R(IDS_SLICE_OUT_OF_BOUNDS));
00846         }
00847         else
00848         {
00849             // should mention that it is pTestSlice->name that is overlapping       
00850             String_256 temp(TEXT(""));
00851             temp.MakeMsg(_R(IDS_SLICES_OVERLAP), (LPCTSTR) m_ErrorStr, (LPCTSTR) strName);
00852 
00853             ErrorInfo Info;
00854             Info.ErrorMsg = 0;
00855             Info.Button[0] = _R(IDS_OK);
00856             Info.Button[1] = _R(IDS_HELP);
00857             Info.OK = 1;
00858             Info.Help = 2;
00859             Info.Title = _R(IDBBL_IMAGESLICE);
00860 
00861             BOOL Again;
00862             do
00863             {
00864                 // Set the error message
00865                 Error::SetError( 0, temp, 0 );
00866 
00867                 Again = FALSE;
00868                 switch (AskQuestion(&Info))
00869                 {
00870                     case _R(IDS_HELP):
00871                         HelpUserTopic(_R(IDS_HELPPATH_Alert_Named_Objects_Overlap));
00872                         Again = TRUE;
00873                         break;
00874                 }
00875             } while (Again);
00876         }
00877     }
00878 
00879     // tidey up before leaving
00880     TidyMosaicList(&MosaicList);
00881 
00882     // end a slow job
00883     // done through the progress class being destroyed
00884 
00885     //  Reset:
00886     BmapPrevDlg::m_bSlicingImage = FALSE;
00887 }

BOOL OpSlice::ExportImageSliceHTML CList< CSlice *, CSlice * > *  pMosaicList,
const String_256 HTMLFile,
INT32  FileNumber = 1
[protected]
 

Creates an HTML file with a table that re-weaves the sliced images back together Also if rollovers have been defined they are also incorperated.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/7/99
Returns:
FALSE if some error occured SideEffect: On m_UsedShimGraphic to set it correctly - assuming it is FALSE to start with.

Definition at line 1749 of file slice.cpp.

01750 {
01751     BOOL InjectFile = m_InjectHTML;
01752 
01753     // varibales used in the inject file and reinject file modes
01754     BYTE * pPreviousHTML = NULL;
01755     DWORD PreviousHTMLSize = 0;
01756     BYTE * pHeadEnd = NULL;
01757     BYTE * pBodyStart = NULL;
01758     BYTE * pBodyStartAbsolute = NULL;
01759     BYTE * pNavDefStart = NULL;
01760     BYTE * pNavDefEnd = NULL;
01761     BYTE * pNavTableStart = NULL;
01762     BYTE * pNavTableEnd = NULL;
01763 
01764     // file doesn't exist? then we cant inject!
01765     CString tempFile(HTMLFile);
01766     if (InjectFile && !FileExists(tempFile))
01767         InjectFile = FALSE;
01768 
01769     if (InjectFile)
01770     {
01771         // read the previous file into memory and identify important locations within it
01772         pPreviousHTML = LoadFileIntoMemory(HTMLFile, PreviousHTMLSize);
01773         if (!pPreviousHTML)
01774             return FALSE;
01775 
01776         // find where the <head> tag finishes
01777         pHeadEnd = FindNextOccuranceOf((BYTE *)&"</head>", pPreviousHTML);
01778         if (!pHeadEnd)
01779             return FALSE;
01780 
01781         // find the navbar definition by looking for the marker comment
01782         // this will be in the header part inside the dummy javascript comment
01783         pNavDefStart = FindNextOccuranceOf((BYTE *)&"<!-- Navbar def -->", pPreviousHTML);
01784         if (pNavDefStart)
01785         {
01786             // find the end of the navbar definition by looking for the marker comment
01787             pNavDefEnd = FindNextOccuranceOf((BYTE *)&"<!-- Navbar def end -->", pNavDefStart);
01788             if (pNavDefEnd)
01789                 pNavDefEnd += 23;
01790         }
01791 
01792         // find where the <body> tag starts & ends
01793         pBodyStartAbsolute = FindNextOccuranceOf((BYTE *)&"<body", pHeadEnd);
01794         if (!pBodyStartAbsolute)
01795             return FALSE;
01796         pBodyStart = FindNextOccuranceOf((BYTE *)&">", pBodyStartAbsolute);
01797         if (!pBodyStart)
01798             return FALSE;
01799 
01800         // the table that holds the navbar is marked by having name tag of "XaraTable"
01801         // find this and the locate the start of the table tag
01802         pNavTableStart = FindNextOccuranceOf((BYTE *)&"name=\"XaraTable", pBodyStart);
01803         if (pNavTableStart)
01804         {
01805             BYTE * pTemp = FindPreviousChar('<', pNavTableStart, pBodyStart);
01806             BYTE * pTemp2 = FindNextOccuranceOf((BYTE *)&"<table", pTemp);
01807 
01808             if (pTemp == pTemp2) // is in start of <table>
01809             {
01810                 pNavTableStart = pTemp;
01811 
01812                 // find the end of the table tag
01813                 pNavTableEnd = FindNextOccuranceOf((BYTE *)&"</table>", pNavTableStart);
01814                 if (pNavTableEnd)
01815                     pNavTableEnd += 8;
01816             }
01817             else
01818                 pNavTableStart = NULL;
01819         }
01820     }
01821 
01822     // injecting HTML where we have injected before?
01823     // ie we have found the markers and can just replace these bits of code
01824     BOOL ReInject = pNavTableEnd ? TRUE : FALSE;
01825 
01826     // open the file to output the HTML
01827     ofstream f(HTMLFile);
01828     if ( !f.is_open() )
01829     {
01830         return FALSE;
01831     }
01832 
01833     POSITION pos = 0;
01834 
01835     if (ReInject)
01836     {
01837         // write the stuff till the start navbar marker
01838         if (pNavDefEnd)
01839             WriteText (f, pPreviousHTML, pNavDefStart - pPreviousHTML);
01840     }
01841     else
01842     {
01843         if (InjectFile)
01844         {
01845             // write everything in the file up to the <\head>
01846             WriteText(f, pPreviousHTML, pHeadEnd - pPreviousHTML);
01847         }
01848         else
01849         {
01850             // export HTML
01851             f << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 transitional//EN\">\n";
01852             f << "<html>\n<head>\n";
01853             f << "<title>Sliced Image</title>\n";
01854         }
01855     }
01856 
01857     // any javascript images go in here
01858 
01859     if (m_FoundRolloverStates)
01860     {
01861         // add the start java button marker
01862         f << "<!-- Navbar def -->\n";
01863 
01864         f << "<script language=\"JavaScript\">\n";
01865         f << "<!-- Dummy comment to hide code from non-JavaScript browsers.\n\n";
01866         f << "if (document.images) {\n";
01867 
01868         // iterate throught the slices for named slices to add their images to the document
01869         pos = pMosaicList->GetHeadPosition();
01870         while (pos)
01871         {
01872             CSlice * pSlice = pMosaicList->GetNext(pos);
01873 
01874             if (pSlice->IsNamedSlice)
01875             {
01876                 for (INT32 i = 0; i < 3 ; i++) // not including SELECTED
01877                     if (m_RolloverState[i].Exists && pSlice->ExistsOnLayerState[i])
01878                     {
01879                         f << pSlice->name;
01880                         f << m_RolloverState[i].Name;
01881                         f << " = new Image(); ";
01882                         f << pSlice->name;
01883                         f << m_RolloverState[i].Name;
01884                         f << ".src = \"";
01885                         f << pSlice->name;
01886                         if (i > 0 && m_RolloverState[i].Exists)
01887                             f << m_RolloverState[i].Name;
01888 
01889                         f << "." << pSlice->FileTypeExtStr;
01890                         f << "\"\n";
01891                     }
01892             }
01893         }
01894         f << "}\n\n";
01895 
01896         // set up the list of graphics
01897         for (INT32 n = 0; n < 3; n++) // not including selected
01898             if (m_RolloverState[n].Exists)
01899             {
01900                 f << "function turn" << m_RolloverState[n].Name;
01901                 f << "(ImageName) {\n";
01902                 f << "\tif (document.images != null) {\n";
01903                 f << "\t\tdocument[ImageName].src = eval(ImageName + \"";
01904                 f << m_RolloverState[n].Name;
01905                 f << ".src\");\n\t}\n";
01906                 //if (n == CLICKED)
01907                 //  f << "return true;\n";
01908                     
01909                 f << "}\n\n";
01910             }
01911 
01912         f << "// End of dummy comment -->\n";
01913         f << "</script>\n";
01914         // mark the end of the java script buttons def
01915         f << "<!-- Navbar def end -->\n";
01916 
01917     } // end of m_FoundRolloverStates - adding rollover start javascript
01918 
01919 
01920     if (ReInject)
01921     {
01922             // write the stuff between the end of the navr bar def and
01923             // the begining of the table
01924         if (pNavDefEnd)
01925             WriteText(f, pNavDefEnd, pNavTableStart - pNavDefEnd);
01926         else
01927             // write the stuff from the begining of the old file to the table start marker
01928             WriteText(f, pPreviousHTML, pNavTableStart - pPreviousHTML);
01929     }
01930     else
01931     {
01932 
01933         f << "</head>\n\n";
01934 
01935         if (InjectFile)
01936         {
01937             // recover the exisitng body tag
01938             WriteText(f, pBodyStartAbsolute, pBodyStart - pBodyStartAbsolute + 1);
01939         }
01940         else
01941         {
01942             // set body tag something like this
01943             f << "<body bgcolor=\"";
01944 
01945             char col[8];
01946             wsprintf(col, "#%02x%02x%02x", (BYTE) m_lRed, (BYTE) m_lGreen, (BYTE) m_lBlue);
01947             f << col;
01948 
01949             f << "\" text=\"";
01950 
01951             // sort out the text colour
01952             if (m_lRed + m_lGreen + m_lBlue < 300)
01953                 f << "white";
01954             else
01955                 f << "black";
01956                 
01957             // set the rest of the body tag
01958             f << "\" link=\"red\" vlink=\"blue\" alink=\"yellow\">\n";
01959         }
01960     }
01961 
01962     // Sliced images are set into a table
01963     f << "<table name=\"XaraTable\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\n";
01964 
01965     BOOL RequireEndOfRowShims = FALSE;
01966     BOOL RequireShimRow = FALSE;
01967     pos = pMosaicList->GetHeadPosition();
01968     while (pos)
01969     {
01970         CSlice * pSlice = pMosaicList->GetNext(pos);
01971         if (pSlice->rowspan > 1)
01972             RequireEndOfRowShims = TRUE;
01973         if (pSlice->colmspan > 1)
01974             RequireShimRow = TRUE;
01975     }
01976 
01977     // add a shim row if there is any colm spanning
01978     if (RequireShimRow)
01979     {
01980         BOOL AddedShimRow = FALSE;
01981         pos = pMosaicList->GetHeadPosition();
01982         INT32 shimcolm = 2; // they are all out of sinc by one so start at 2!?!
01983                             // never mind they only have to be (nearly) all there and in order
01984         while (pos)
01985         {
01986             CSlice * pSlice = pMosaicList->GetNext(pos);
01987 
01988             if (pSlice->colm == shimcolm)
01989             {
01990                 // add the shim row if required and we found something to put in it
01991                 if (!AddedShimRow)
01992                 {
01993                     f << "<!-- shim row--><tr>";
01994                     AddedShimRow = TRUE;
01995                 }
01996 
01997                 // output the HTML for the shim
01998                 f << "<td><img src=\"shim.gif\" width=\"" << pSlice->colmwidth/750 << "\" height=\"1\" border=\"0\"></td>\n";
01999                 shimcolm++;
02000                 m_UsedShimGraphic = TRUE;
02001                 // start looking for the next colm width from the begining of the list
02002                 // since the x co-ord is not ordered directly through the list
02003                 pos = pMosaicList->GetHeadPosition();
02004             }
02005         }
02006 
02007         // if we started the row - end it here
02008         if (AddedShimRow)
02009         {
02010             // add the last tag (unknown width, but then we dont need to know this width
02011             // just fill the cell in with a shim
02012             f << "<td><img src=\"shim.gif\"";
02013             if (RequireEndOfRowShims) // if we have end of row shims expand this shim into the top corner with a colm span of 2
02014                 f << " colspan=\"2\"";
02015             f << " height=\"1\" border=\"0\"></td>\n</tr>\n\n";
02016         }
02017     }
02018 
02019     // loop round all entries in the list
02020     pos = pMosaicList->GetHeadPosition();
02021     
02022     INT32 CurrentRow = 0;
02023 
02024     while (pos)
02025     {
02026         CSlice * pSlice = pMosaicList->GetNext(pos);
02027         
02028         if (pSlice->row > CurrentRow)
02029         {
02030             // finish the last row off
02031             if (CurrentRow > 0)
02032             {
02033                 // add a shim for the row height
02034                 if (RequireEndOfRowShims)
02035                 {
02036                     f << "<td><img src=\"shim.gif\" width=\"1\" height=\"" << pSlice->rowheight/750 << "\" border=\"0\"></td>";
02037                     m_UsedShimGraphic = TRUE;
02038                 }
02039 
02040                 // finish off the row
02041                 f << "</tr>\n\n";
02042             }
02043                 
02044             CurrentRow = pSlice->row;
02045             // start a new row
02046             f << "<!-- Row " << CurrentRow << " --><tr>\n";
02047         }
02048 
02049         // add the table entry for this slice
02050         // open the table data entry
02051         f << "<td";
02052         
02053         // add spanning data
02054         if (pSlice->rowspan > 1)
02055             {
02056             f << " rowspan=\"" << pSlice->rowspan << "\"";
02057             }
02058         
02059         if (pSlice->colmspan > 1)
02060             {
02061             f << " colspan=\"" << pSlice->colmspan << "\"";
02062             }
02063         // end the table definition start entry
02064         f << ">";
02065 
02066         // debug data
02067         //f << "<!-- ";
02068         //f << "(" << pSlice->top << "," << pSlice->left << "),(" << pSlice->bottom << "," << pSlice->right << ") ";
02069         //f << " row " << pSlice->row << " colm " << pSlice->colm << " ";
02070         //f << " --> ";
02071 
02072         // so we know when to close it
02073         BOOL AddedAnchor = FALSE;
02074         
02075         // Add the anchor data if this is a rollover
02076         // and it is not the selected state button
02077         if ( (m_FoundRolloverStates || pSlice->HasURL)
02078             && pSlice->IsNamedSlice 
02079             && (FileNumber != pSlice->ButtonNumber || !m_RolloverState[SELECTED].Exists))
02080         {
02081             //<a href="Index.htm" onmouseover="turnmouse('general_info')" onmouseout="turnoff('general_info')" onclick="turnon('general_info')" >
02082             f << "<a href = \"";
02083             AddedAnchor = TRUE;
02084 
02085             // link in destination of the link]
02086             if (m_pLinkName && pSlice->ButtonNumber > 0 && (pSlice->HasURL || pSlice->ExistsOnLayerState[SELECTED]))
02087             {
02088                 f << m_pLinkName[pSlice->ButtonNumber - 1];
02089                 f << "\"";
02090 
02091                 if (pSlice->pFrameText && *(pSlice->pFrameText))
02092                 {
02093                     f << " TARGET=\"";
02094                     f << pSlice->pFrameText;
02095                     f << "\"";
02096                 }
02097             }
02098             else
02099             {
02100                 f << m_PathName.GetFileName(FALSE); // just the name stem of the HTML file please
02101                 f << ".";
02102                 f << m_HTMLext;
02103                 f << "\"";
02104             }
02105 
02106             if (m_FoundRolloverStates)
02107             {
02108                 if (m_RolloverState[MOUSE].Exists && pSlice->ExistsOnLayerState[MOUSE])
02109                 {
02110                     // add mouse state
02111                     f << " onmouseover=\"turn";
02112                     f << m_RolloverState[MOUSE].Name;
02113                     f << "('";
02114                     f << pSlice->name;
02115                     f << "')\"";
02116                 }
02117 
02118                 if (pSlice->ExistsOnLayerState[DEFAULT])
02119                 {
02120                     // add default state state
02121                     f << " onmouseout=\"turn";
02122                     f << m_RolloverState[DEFAULT].Name;
02123                     f << "('";
02124                     f << pSlice->name;
02125                     f << "')\"";
02126                 }
02127 
02128                 if (m_RolloverState[CLICKED].Exists && pSlice->ExistsOnLayerState[CLICKED])
02129                 {
02130                     // add click state
02131                     f << " onmousedown=\"turn";
02132                     f << m_RolloverState[CLICKED].Name;
02133                     f << "('";
02134                     f << pSlice->name;
02135                     f << "')\"";
02136                 }
02137             }
02138 
02139             f << ">";
02140         }
02141 
02142         // add the slice image
02143         f << "<img name=\"";
02144         f << pSlice->name;
02145         f << "\" src=\"";
02146             
02147         if (!pSlice->IsEmpty)
02148         {   
02149             f << pSlice->name;
02150 
02151             // if this is the selected page and the selected button
02152             // show the selected graphic not the default one
02153             // by adding the word "selected" after the name
02154             if (FileNumber == pSlice->ButtonNumber && m_RolloverState[SELECTED].Exists && pSlice->ExistsOnLayerState[SELECTED])
02155                 f << m_RolloverState[SELECTED].Name;
02156 
02157             f << "." + pSlice->FileTypeExtStr;
02158         }
02159         else // it was just blank anyway so use the shim instead
02160         {
02161             f << "shim.gif";
02162             m_UsedShimGraphic = TRUE;
02163         }
02164 
02165         f << "\"";
02166 
02167         // add alternative text
02168         if (pSlice->IsNamedSlice)
02169         {
02170             f << " alt=\"";
02171             f << TurnUnderScoreIntoSpace(pSlice->name);
02172             f << "\"";
02173         }
02174 
02175         // use the matrix to work out the pixel values of height and width
02176         Matrix Identity;
02177         DocRect r(pSlice->left, pSlice->top, pSlice->right, pSlice->bottom);
02178         WinRect Rect = OSRenderRegion::BitmapDocRectToWin( Identity, r, 96.0 );
02179 
02180         // bitmap width
02181         f << " width=\"" << Rect.right - Rect.left <<"\"";
02182         
02183         // bitmap height
02184         f << " height=\"" << Rect.bottom - Rect.top <<"\"";
02185         
02186         // finish the image tag
02187         f << " border=\"0\">";
02188         
02189         // chose the anchor tag if this is a rollover
02190         if (AddedAnchor)
02191         {
02192             f << "</a>";
02193         }
02194 
02195         // close the table definition entery
02196         f << "</td>\n";
02197     }
02198 
02199     // add a shim to the end of the last row if needed
02200     if (RequireEndOfRowShims)
02201     {
02202         f << "<td><img src=\"shim.gif\" width=\"1\" border=\"0\"></td>";
02203         m_UsedShimGraphic = TRUE;
02204     }
02205 
02206     // end the last row
02207     f << "</tr>\n";
02208     
02209     // end the table
02210     f << "</table>\n";
02211 
02212     if (ReInject)
02213     {
02214         // copy the data from the end of the table to the end of the file
02215         WriteText(f, pNavTableEnd, PreviousHTMLSize - (pNavTableEnd - pPreviousHTML));
02216     }
02217     else
02218     {
02219         if (InjectFile)
02220         {
02221             // write everything from after the <body> tag onwards
02222             WriteText(f, pBodyStart+1, PreviousHTMLSize - (pBodyStart+1 - pPreviousHTML));
02223         }
02224         else
02225         {
02226             // close the html file
02227             f << "<p>\n\n</body>\n</html>\n";
02228         }
02229     }
02230 
02231     // close the file
02232     f.close();
02233     
02234     // we are done with the old HTML file in memory
02235     if (pPreviousHTML)
02236         delete [] pPreviousHTML;
02237 
02238     return TRUE;
02239 }

BOOL OpSlice::ExportRollOverSlice CSlice pSlice,
BitmapExportOptions pExportOptions
[protected]
 

Exports all the rollover states of this given slice if they are defined.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/8/99
Returns:
FALSE if any of the exports failled

Definition at line 2463 of file slice.cpp.

02464 {
02465     BOOL ok = TRUE;
02466 
02467     for (INT32 i = 0 ; ok && i < 4 ; i++)
02468     {
02469 
02470         if (m_RolloverState[i].Exists && (i == 0 || pSlice->ExistsOnLayerState[i]))
02471         {
02472             // hide other button layers and show this button layer
02473             ShowRolloverLayer(i);
02474             String_256 StateName = pSlice->name;
02475 
02476             if (i > 0)
02477                 StateName += m_RolloverState[i].Name;
02478 
02479             // make sure this named object is fully selected
02480             if (pSlice->IsNamedSlice)
02481             {
02482                 // do this by calling the select scan on it
02483                 SGNameItem* pItem = SliceHelper::LookupNameGalleryItem(pSlice->name);
02484                 if (pItem)
02485                 {
02486                     SelectScan scanner(pItem, SelectScan::SELECT);
02487                     scanner.Scan();
02488                 }
02489             }
02490 
02491             // export the graphic
02492             ok = ExportSliceGraphic(pSlice, pExportOptions, StateName);
02493         }
02494     }
02495 
02496     // restore layers to as they were
02497     ShowRolloverLayer(ORIGINAL_LAYERS);
02498 
02499     return ok;
02500 }

BOOL OpSlice::ExportSliceGraphic CSlice pSlice,
BitmapExportOptions pExportOptions,
const String_256 GraphicFileName
[protected]
 

Generates a graphic of a section of the whole image defined by the rectangular area of the slice. Params: pSlice - the slice to export contains area rect and name.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/7/99
Returns:
FALSE if some error occured

Definition at line 1588 of file slice.cpp.

01589 {
01590     // This is the clip rect that is required to be in spread co-ords
01591     DocRect r(pSlice->left, pSlice->top, pSlice->right, pSlice->bottom);
01592 
01593     // Get the export filter for this slice if
01594     // it is a named slice and has been exported before in which case get
01595     // its type and its exportoptions (if the user wishes to use them)
01596     // and use those instead
01597     BitmapExportOptions * pOverRideExportOptions = pExportOptions;
01598     SGNameItem* pItem = SliceHelper::LookupNameGalleryItem(pSlice->name);
01599     if (!pItem && pSlice->IsNamedSlice)
01600     {
01601         // someone may have mundged the slice name due to javascript and filename requirements
01602         // will have to mundge each gallery name in turn since we didn't find a direct match
01603         NameGallery * pNameGallery = NameGallery::Instance();
01604         SGUsedNames* pNames = pNameGallery ? pNameGallery->GetUsedNames() : NULL;
01605         pItem = pNames ? (SGNameItem*) pNames->GetChild() : NULL;
01606 
01607         BOOL Found = FALSE;
01608 
01609         String_256 str;
01610 
01611         // check all the name gallery items
01612         while (pItem && !Found)
01613         {
01614             pItem->GetNameText(&str);
01615 
01616             // do the mundge
01617             RemoveIlligalFileAndJavaChars(str);
01618 
01619             // if the name matches its your man
01620             if (pSlice->name.CompareTo(str) == 0)
01621                 Found = TRUE;
01622             else
01623                 // no then try the next one?
01624                 pItem = (SGNameItem *) pItem->GetNext();
01625         }
01626     }
01627 
01628     if (pItem)
01629     {
01630         NodeSetProperty* pPropNode = pItem->GetPropertyNode();
01631         if (pPropNode)
01632         {
01633             NamedExportProp * pProp = (NamedExportProp*) pPropNode->GetProperty(NamedExportProp::nIndex);
01634             if (pProp && pProp->GetOptions() && !pProp->IsVirgin())
01635             {   // update the slice to use this name and export type
01636                 pOverRideExportOptions = pProp->GetOptions();
01637 
01638                 //PathName TempPath = pOverRideExportOptions->GetPathName();
01639                 //pSlice->FileTypeExtStr = TempPath.GetType();
01640 
01641                 // have to use the ptr class type on the options to work out which filter to use (not very good really)
01642                 if (IS_A(pOverRideExportOptions, JPEGExportOptions))
01643                 {
01644                     pSlice->FileTypeExtStr = "jpg";
01645                 }
01646                 else if (IS_A(pOverRideExportOptions, BMPExportOptions))
01647                 {
01648                     pSlice->FileTypeExtStr = "bmp";
01649                 }
01650                 else if (IS_A(pOverRideExportOptions, PNGExportOptions))
01651                 {
01652                     pSlice->FileTypeExtStr = "png";
01653                 }
01654                 else if (IS_A(pOverRideExportOptions, GIFExportOptions))
01655                 {
01656                     pSlice->FileTypeExtStr = "gif";
01657                 }
01658                 else // not a type we can deal with from here
01659                     pOverRideExportOptions = pExportOptions;
01660             }
01661         }
01662     }
01663 
01664     // set up the path of where to save it
01665     PathName Path = m_PathName;
01666     Path.SetFileName(GraphicFileName);
01667     Path.SetType(pSlice->FileTypeExtStr);
01668 
01669     // use screen AA for all image slicing
01670     pOverRideExportOptions->SetAntiAliasing(MAINTAIN_SCREEN_AA);
01671 
01672     // since we have been messing around with the rect to export and the layers we
01673     // should assume that the palette we hold is no longer valid
01674     pOverRideExportOptions->BitmapSourceHasChanged();
01675 
01676     CCDiskFile File;
01677     if(!File.open(Path.GetPath(), ios::in | ios::out | ios::binary))
01678         return FALSE;       // error!
01679 
01680     // have to use the ptr class type on the options to work out which filter to use (not very good really)
01681     if (IS_A(pOverRideExportOptions, JPEGExportOptions))
01682     {
01683         JPEGExportFilter ExportFilter;
01684         ExportFilter.DoExportWithOptions(this, &File, &Path, 
01685                                         Document::GetCurrent(),
01686                                         (JPEGExportOptions*) pOverRideExportOptions, &r);
01687     }
01688     else if (IS_A(pOverRideExportOptions, BMPExportOptions))
01689     {
01690         BMPFilter ExportFilter;
01691         ExportFilter.DoExportWithOptions(this, &File, &Path, 
01692                                         Document::GetCurrent(),
01693                                         (BMPExportOptions*) pOverRideExportOptions, &r);
01694     }
01695     else if (IS_A(pOverRideExportOptions, PNGExportOptions))
01696     {
01697         PNGFilter ExportFilter;
01698         ExportFilter.DoExportWithOptions(this, &File, &Path, 
01699                                         Document::GetCurrent(),
01700                                         (PNGExportOptions*) pOverRideExportOptions, &r);
01701     }
01702     else if (IS_A(pOverRideExportOptions, GIFExportOptions))
01703     {
01704         TI_GIFFilter ExportFilter;
01705         ExportFilter.DoExportWithOptions(this, &File, &Path, 
01706                                         Document::GetCurrent(),
01707                                         (GIFExportOptions*) pOverRideExportOptions, &r);
01708     }
01709 
01710     File.close();
01711 
01712     // integrate with Dream Weaver by creating design notes for each exported graphic file
01713     if (m_UsesDesignNotes && pExportOptions->GetCanUseDesignNotes())
01714     {
01715         CString DocName(Document::GetCurrent()->GetLocation()); 
01716         DocName += TEXT("\\") + Document::GetCurrent()->GetPathName();
01717 
01718         if (DocName == TEXT("\\"))
01719         {
01720             InformWarning (_R(IDS_NOTES_WARNING));
01721             m_UsesDesignNotes = FALSE;
01722         }
01723         else
01724         {
01725             CString GraphicFile(Path.GetPath());
01726 
01727             // create or modify a .mno forward source file
01728             CreateDesignNoteWithForwardSource(GraphicFile, DocName);
01729         }
01730     }
01731 
01732 
01733     return TRUE;
01734 }

void OpSlice::FailledToExportHTML const String_256 file  )  [protected]
 

Puts up an error msg saying that it could export the HTML and marks it as unexported Param file - The file it failled to export Returns.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/2/00

Definition at line 2950 of file slice.cpp.

02951 {
02952     TCHAR prompt[256];
02953     if (!::LoadString( AfxGetResourceHandle(), _R(IDS_FAILED_EXPORT_HTML), prompt, 256 ) )
02954         camStrcpy( prompt, "%s?" );                             // in case cannot load
02955 
02956     // fill in the %s field with the filename
02957     TCHAR ErrorMsg[512];
02958     wsprintf( ErrorMsg, prompt, (LPCTSTR) file );
02959     Error::SetError( 0, ErrorMsg, 0 );
02960     SetNextMsgHelpContext(_R(IDM_OVERWRITE));
02961     InformLastError();
02962     m_ExportedHTMLOK = FALSE; // since we don't want to ask the user to view it if we didn't export it do we?
02963 }

BYTE * OpSlice::FindNextOccuranceOf BYTE *  pSearch,
BYTE *  pFrom
[static, protected]
 

Finds the next occurance of a string in the other large 'string'. Pass in lowercase and it will match with uppercase letters Param pSearch - The shorter string being searched for pFrom - The larger string to find it in Returns a ptr to the memory where the search string was located nearest to the starting point, or NULL if it wasn't found.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/2/00

Definition at line 2863 of file slice.cpp.

02864 {
02865     ASSERT(pFrom);
02866     ASSERT(pSearch);
02867     INT32 i = 0;
02868     while (*pFrom)
02869     {
02870         i = 0;
02871         while (*(pSearch+i) == *(pFrom + i) || *(pSearch+i) == *(pFrom + i) + 32 /*+ 'a' - 'A'*/)
02872         {
02873             i++;
02874             if (*(pSearch + i) == 0)
02875                 return pFrom;
02876         }
02877         pFrom++;
02878     }
02879 
02880     return NULL;
02881 }

BYTE * OpSlice::FindPreviousChar char  Search,
BYTE *  pFrom,
BYTE *  pLimit
[static, protected]
 

Definition at line 2884 of file slice.cpp.

02885 {
02886     BOOL found = FALSE;
02887     while (pFrom >= pLimit && !found)
02888     {
02889         if ((char)*pFrom == Search)
02890             found = TRUE;
02891         else
02892             pFrom--;
02893     }
02894 
02895     return found ? pFrom : NULL;
02896 }

CSlice * OpSlice::GetButtonNumber CList< CSlice *, CSlice * > *  pMosaicList,
INT32  buttonno
[protected]
 

Definition at line 1559 of file slice.cpp.

01560 {
01561     POSITION ToDo = pMosaicList->GetHeadPosition();
01562     while (ToDo)
01563     {
01564         CSlice * pTestSlice = pMosaicList->GetNext(ToDo);
01565 
01566         // and while we are here set the button number
01567         if (pTestSlice->IsNamedSlice && pTestSlice->ButtonNumber == buttonno)
01568         {
01569             return pTestSlice;
01570         }
01571     }
01572 
01573     return NULL;
01574 }

OpState OpSlice::GetState String_256 ,
OpDescriptor
[static]
 

This item is always available, so long as a document is visible. Not really sure if I even need this!!!

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/99

Reimplemented from OpMenuImport.

Definition at line 946 of file slice.cpp.

00947 {
00948     OpState OpSt;
00949 
00950     // if we don't allow it
00951     OpSt.Greyed = TRUE;
00952     Spread* pSpread = Document::GetSelectedSpread();
00953     if (pSpread && !pSpread->FindActiveLayer()->IsFrame())
00954         OpSt.Greyed = FALSE;
00955 
00956     return OpSt;
00957 }

BOOL OpSlice::Init void   )  [static]
 

Declares the OpDescriptor.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/99
Returns:
TRUE if worked, FALSE if failed (out of memory)

Errors: -

Reimplemented from OpMenuImport.

Definition at line 253 of file slice.cpp.

00254 {
00255     return RegisterOpDescriptor(
00256             0,                          // Tool ID
00257             _R(IDS_IMAGESLICE),                 // String resource ID
00258             CC_RUNTIME_CLASS(OpSlice),  // Runtime class
00259             OPTOKEN_IMAGESLICE,         // Token string
00260             GetState,                   // GetState function
00261             _R(IDH_Command_Import_from_Web),// help ID GTODO: Is this needed?
00262             _R(IDBBL_IMAGESLICE),           // bubble help
00263             _R(IDD_BARCONTROLSTORE),        // resource ID
00264             _R(IDC_IMAGESLICE),             // control ID
00265             SYSTEMBAR_FILE,             // Bar ID
00266             TRUE,                       // Receive system messages
00267             FALSE,                      // Smart duplicate operation
00268             TRUE,                       // Clean operation
00269             0,      // String for one copy only error
00270             (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags
00271         );
00272     
00273 }

BOOL OpSlice::InRect CSlice pRect,
INT32  x,
INT32  y
[protected]
 

Tests if the point X,Y is in the rectangle defined by the slice.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/7/99
Returns:
TRUE if x,y is in the rect

Definition at line 1081 of file slice.cpp.

01082 {
01083     if (x > pRect->left && x < pRect->right
01084         && y > pRect->top && y < pRect->bottom)
01085         return TRUE;
01086         
01087     return FALSE;
01088 }

BYTE * OpSlice::LoadFileIntoMemory String_256  FileName,
DWORD Size
[static, protected]
 

Creates a copy of the file in memory and says how big it is Param Filename - The file to open Size - Fills in this param with the size of the memory object created Returns a ptr to the memory, or NULL if it failled.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/2/00

Definition at line 2828 of file slice.cpp.

02829 {
02830     Size = 0;
02831     CFile file (FileName, CFile::modeRead );
02832     DWORD BytesToRead = file.GetLength();
02833 
02834     if (!BytesToRead)
02835         return NULL;
02836 
02837     BYTE * pBits = new BYTE[BytesToRead + 1];
02838 
02839     if (!pBits)
02840         return NULL;
02841 
02842     Size = file.Read(pBits, BytesToRead) + 1;
02843 
02844     // set the last bit as zero so we can use string functions on the file!
02845     *(pBits + BytesToRead) = 0; 
02846 
02847     return pBits;
02848 }

void OpSlice::MarkEmptySlices CList< CSlice *, CSlice * > *  pMosaicList,
DocRect SelRect,
BitmapExportOptions pExportOptions
[protected]
 

What it is meant to do is check if the drawing has anything that is visible within this slice. So if there is nothing visible don't bother generating a graphic for it. Any empty slices are set as empty in the list of slices. Method used is to render the image to be exported as a 32bit graphic and then check the alpha channel for anything non-transparent. Param pMoasicList - List of the slices SelRect - The rect of the image being exported Returns - Errors Not putting a graphic into the HTML table may screw up the sizing of cells in the table if it was relying on this cell to get the size information. So instead I re-use the shim graphic expanded to that size (see the ExportHTML fn).

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/10/99

Definition at line 2616 of file slice.cpp.

02617 {
02618     // get the selection
02619     SelRange Sel(*(GetApplication()->FindSelection()));
02620 
02621     // set the range flags so it includes shadow and bevel manager nodes
02622     RangeControl rg = Sel.GetRangeControlFlags();
02623     rg.PromoteToParent = TRUE;
02624     rg.CrossLayer = TRUE;
02625     Sel.Range::SetRangeControl(rg);
02626     Sel.Update(FALSE);
02627 
02628     BOOL RenderedBmp = FALSE;
02629 
02630     OILBitmap* pOilBmp = NULL;
02631     UINT32 Width = 0;
02632     UINT32 Height = 0;
02633     
02634     POSITION ToDo = pMosaicList->GetHeadPosition();
02635 
02636     while (ToDo)
02637     {
02638         CSlice * pTopSlice = pMosaicList->GetNext(ToDo);
02639 
02640         // we will want to export all named slices
02641         // don't export any none-named slices that are blank
02642         // these are marked as empty
02643         if (!pTopSlice->IsNamedSlice)
02644         {
02645             // create the bmp of the selection if we haven't done so
02646             if (!RenderedBmp)
02647             {
02648                 SelectionState SelState;
02649                 SelState.Record();
02650 
02651                 // no selection implies exporting the lot
02652                 if (Sel.IsEmpty() || (pExportOptions && !pExportOptions->IsBackgroundTransparent()) )
02653                 {
02654                     // select everything
02655                     //NodeRenderableInk::SelectAllInRect(SelRect, Document::GetSelectedSpread());
02656                     // select everything
02657                     DocRect SpreadBounds = BaseBitmapFilter::GetSizeOfDrawing(Document::GetSelectedSpread()); // returns in spread co-ords ignoring silly layers
02658                     NodeRenderableInk::SelectAllInRect(SpreadBounds, Document::GetSelectedSpread());
02659 
02660                     SelRange NewSel(*(GetApplication()->FindSelection()));
02661                     // set the range flags so it includes shadow and bevel manager nodes
02662                     RangeControl rg = NewSel.GetRangeControlFlags();
02663                     rg.PromoteToParent = TRUE;
02664                     rg.CrossLayer = TRUE;
02665                     NewSel.Range::SetRangeControl(rg);
02666                     NewSel.Update(FALSE);
02667 
02668                     // render a bitmap of the entire image being exported (all slices)
02669                     pOilBmp = CBMPBits::RenderSelectionToBMP(&NewSel, 32, TRUE, &SelRect);
02670                 }
02671                 else
02672                 {
02673                     // render a bitmap of the entire image being exported (all slices)
02674                     pOilBmp = CBMPBits::RenderSelectionToBMP(&Sel, 32, TRUE, &SelRect);
02675                 }
02676 
02677                 SelState.Restore();
02678                 
02679                 if (!pOilBmp)
02680                     return;
02681 
02682                 Width = pOilBmp->GetWidth();
02683                 Height = pOilBmp->GetHeight();
02684 
02685                 RenderedBmp = TRUE; // since we only want to do this once!
02686 
02687                 /*
02688                 // add the bitmap to the bitmap list
02689                 KernelBitmap* PreConvOffscreenBitmap = new KernelBitmap(pOilBmp,TRUE);
02690                 KernelBitmap* copy1 = DIBUtil::CopyKernelBitmap(PreConvOffscreenBitmap,FALSE);  // FALSE to ensure OIL gets added to globalbmp list
02691                 OILBitmap* pOil1 = (OILBitmap*) copy1->GetActualBitmap();
02692                 pOil1->SetName(String_256("PreConvertedBitmap"));
02693                 copy1->Attach(Document::GetCurrent()->GetBitmapList());
02694                 delete PreConvOffscreenBitmap;
02695                 */
02696             }
02697 
02698             BOOL FoundABit = FALSE;
02699 
02700             // calculate sizes and start positions for the scan
02701 
02702             UINT32 x = (pTopSlice->left - SelRect.lox) * Width / (SelRect.hix - SelRect.lox);
02703             UINT32 y = (pTopSlice->top - SelRect.loy) * Height / (SelRect.hiy - SelRect.loy);
02704 
02705             UINT32 StartX = x;
02706 
02707             UINT32 EndX = min( Width, (pTopSlice->right - SelRect.lox) * Width / (SelRect.hix - SelRect.lox));
02708             UINT32 EndY = min(Height, (pTopSlice->bottom - SelRect.loy) * Height / (SelRect.hiy - SelRect.loy));
02709 
02710             TRACE( _T("marking slice "));
02711             TRACE(pTopSlice->name);
02712             TRACE( _T("\nfrom (%d,%d) to (%d,%d)\n"), x,y, EndX, EndY);
02713             Pixel32bpp Val;
02714 
02715             // scan this slices part of the bitmap
02716             if (pOilBmp)
02717                 while (!FoundABit && y < EndY)
02718                 {
02719                     x = StartX;
02720 
02721                     while (!FoundABit && x < EndX)
02722                     {
02723                         Val = pOilBmp->ReadPixel32bpp(x,y);
02724 
02725                         // check the alpha of each pixel in the 32bit bitmap of the slice
02726                         if (Val.Alpha != 255)
02727                             FoundABit = TRUE;
02728 
02729                         x++;
02730                     }
02731                     y++;
02732                 }
02733 
02734             // mark as empty
02735             if (!FoundABit)
02736             {
02737                 pTopSlice->IsEmpty = TRUE;
02738                 TRACE( _T("Is Empty\n"));
02739             }
02740         }
02741     }
02742 }

void OpSlice::NudgeSliceIfClose INT32 &  Ax,
INT32 &  Ay,
INT32 &  Cx,
INT32 &  Cy,
CList< CSlice *, CSlice * > *  pMosaicList
[protected]
 

Moves the new slice over a bit if it just overlaps with an existing slice due to the pixel infation. It does this by adjusting the AC rectangle passed in.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/8/99
Returns:
nothing

Definition at line 1202 of file slice.cpp.

01203 {
01204     INT32 OldAx = Ax;
01205     INT32 OldAy = Ay;
01206     INT32 OldCx = Cx;
01207     INT32 OldCy = Cy;
01208 
01209     BOOL done = FALSE;
01210 
01211     // allow how many pixels to be fudged?
01212     for (INT32 size = 750 ; size <= 1500 && !done ; size += 750)
01213     {
01214         POSITION pos = pMosaicList->GetHeadPosition();
01215 
01216         while (pos)
01217         {
01218             CSlice * pRect = pMosaicList->GetNext(pos);
01219             if (!pRect->name.IsEmpty())
01220             {
01221                 if (pRect->bottom - size == OldAy  && OldCy != pRect->bottom)
01222                 {
01223                     if (size == 750)
01224                     {
01225                         Ay = pRect->bottom;
01226                         done = TRUE;
01227                     }
01228                     else
01229                     {
01230                     // anything in the whole slice list that equals pRect->bottom should be reduced by 750
01231                     // and the same for all the others
01232                         //Ay = pRect->bottom - 750;
01233                         ReAlignEdge ( pRect->bottom, Ay, FALSE, pMosaicList);
01234                         done = TRUE;
01235                     }
01236                 }
01237                 if (pRect->top + size == OldCy && OldAy != pRect->top)
01238                 {
01239                     if (size == 750)
01240                     {
01241                         Cy = pRect->top;
01242                         done = TRUE;
01243                     }
01244                     else
01245                     {
01246                         //Cy = pRect->top + 750;
01247                         ReAlignEdge ( pRect->top, Cy, FALSE, pMosaicList);
01248                         done = TRUE;
01249                     }
01250                 }
01251                 if (pRect->left + size == OldCx && OldAx != pRect->left)
01252                 {
01253                     if (size == 750)
01254                     {
01255                         Cx = pRect->left;
01256                         done = TRUE;
01257                     }
01258                     else
01259                     {
01260                         //Cx = pRect->left + 750;
01261                         ReAlignEdge ( pRect->left, Cx, TRUE, pMosaicList);
01262                         done = TRUE;
01263                     }
01264                 }
01265                 if (pRect->right - size == OldAx && OldCx != pRect->right)
01266                 {
01267                     if (size == 750)
01268                     {
01269                         Ax = pRect->right;
01270                         done = TRUE;
01271                     }
01272                     else
01273                     {
01274                         //Ax = pRect->right - 750;
01275                         ReAlignEdge ( pRect->right, Ax, TRUE, pMosaicList);
01276                         done = TRUE;
01277                     }
01278                 }
01279             }
01280         }
01281     }
01282 }

void OpSlice::PixelAlignedInflate DocRect r  )  [protected]
 

Infates a DocRect to the nearest pixel aligned boundary.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/7/99

Definition at line 2250 of file slice.cpp.

02251 {
02252     INT32 lox, loy, hix, hiy = 0;
02253     
02254     lox = ((r->lox)/750) * 750; // likely round down
02255     loy = ((r->loy)/750) * 750;
02256     hix = ((r->hix + 749)/750) * 750; // likely round up
02257     hiy = ((r->hiy + 749)/750) * 750;
02258 
02259     DocRect newr(lox, loy, hix, hiy);
02260     *r = newr;
02261 }

void OpSlice::RemoveIlligalFileAndJavaChars String_256 Str  )  [protected]
 

Replaces any illigal chars in the Str as far as filenames and use as javascript variables for use in rollovers is concerned.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/8/99

Definition at line 2557 of file slice.cpp.

02558 {
02559     INT32 i = 0;
02560 
02561     while (Str[i])
02562     {
02563         char stri = Str[i];
02564 
02565         if ((stri < 'a' || stri > 'z') && (stri < 'A' || stri > 'Z') && (stri < '0' || stri > '9')
02566             && (stri != '#' && stri != '$') )
02567         {
02568             *((TCHAR *) Str +i) = (TCHAR)'_';
02569         }
02570 
02571         i++;
02572     }
02573 }

BOOL OpSlice::SaveFileDlg  )  [protected]
 

Brings up the save dlg to ask the user where to save the html and the slices too. Also has the filter selection to choose from when picking the default slice. Sets the path location, name and graphic type into the variable m_PathName.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/7/99
Returns:
TRUE if the user clicks save, FALSE otherwise

Definition at line 2278 of file slice.cpp.

02279 {
02280     // Set up the dialog
02281 
02282     // list of filters available is a cut down version of the filter list
02283     // offering just the bitmap versions
02284     String_256 FilterString(_R(IDS_SLICE_USABLE_FILTERS));
02285 
02286     // Get the filename.
02287     String_256 Str("untitled.htm");
02288 
02289     // Build a pathname out of it
02290     PathName Path(Str);
02291 
02292     // Get some details, ready for the dialog
02293     String_256 LocString = Path.GetLocation(FALSE);
02294     String_256 NameString = Path.GetFileName();
02295 
02296     // create a dialog and use the path and name of the file if available, or
02297     // use the default path if not.
02298     String_256 DocName = Document::GetCurrent()->GetDocName();
02299 
02300     // Sorry about the INT32 names, but we are into OS Specific scary stuff here
02301     // Under Windows 95 the OnFileNameOK() function of CFileDialog does not work
02302     // As a Result we have to do the tests ourselves afterwards under win95
02303     // by default we do not need to put the dialog up
02304     BOOL WeNeedToPutSaveAsDialogUpAgain = FALSE;
02305     
02306     // try the dialog
02307     do
02308     {
02309         // Default to only putting the dialog up the once.
02310         WeNeedToPutSaveAsDialogUpAgain = FALSE;
02311 
02312         // Create and display prepare the dialog
02313         SliceSaveFileDlg /*SaveFileDialog*/ SaveDialog(FilterString, LocString, NameString, DocName);
02314         SaveDialog.PrepareDialog();
02315         CString temp;
02316         
02317         temp.LoadString(_R(IDS_SLICE_EXPORT_TITLE));
02318         SaveDialog.m_ofn.lpstrTitle = temp;
02319 
02320         // Display the dialog
02321         BOOL Result = SaveDialog.OpenAndGetFileName();
02322         m_InjectHTML = SaveDialog.m_Inject; // did we ask to inject the HTML?
02323 
02324         // If they did not click on OK then stop right now
02325         if (!Result)
02326             return FALSE;
02327 
02328         // Make sure that the file name is OK
02329         // we only need to do this under windows 95, as other OS's will have already done it
02330         // Disable for VC4.0/MFC 4.0 as they have fixed it.
02331     #if _MFC_VER < 0x400
02332         if (IsWin32c())
02333         {   
02334             //TRACE( _T("Windows 95, testing for same file name after the event\n"));
02335             if (!SaveDialog.IsValidFilename()) WeNeedToPutSaveAsDialogUpAgain = TRUE;
02336         }
02337     #endif
02338 
02339         // Get the filename.
02340         CString TempName(SaveDialog.m_ofn.lpstrFile);
02341         SaveDialog.AppendExtension(&TempName);
02342         Str = String_256(TempName);
02343         Path = PathName(Str);
02344 
02345         // read the filter type to use
02346         // if the user hasn't picked (or typed) one of this list
02347         // then make it a gif.
02348         // Otherwise set the Path Type to store the default type for each slice made
02349         if (Path.GetType() != "jpg" && Path.GetType() != "bmp" && Path.GetType() != "gif" && Path.GetType() != "png")
02350             switch(SaveDialog.GetSelectedFilterIndex())
02351             {
02352             default:
02353             case 1:
02354                 Path.SetType("gif");
02355                 break;
02356             case 2:
02357                 Path.SetType("jpg");
02358                 break;
02359             case 3:
02360                 Path.SetType("bmp");
02361                 break;
02362             case 4:
02363                 Path.SetType("png");
02364                 break;
02365             }
02366 
02367         // Extract directory name (minus terminating backslash) and remember for next time.
02368         SaveDialog.SetDefaultPath(Path.GetLocation(FALSE));
02369 
02370     } while(WeNeedToPutSaveAsDialogUpAgain);
02371 
02372     // Put the file name into the var set aside for it
02373     m_PathName = Path;
02374 
02375     return TRUE;
02376 }

BOOL OpSlice::ScanForRolloverStates CList< CSlice *, CSlice * > *  pMosaicList  )  [protected]
 

Sets the m_RolloverState member variable by scanning the layers and finding out what specail named layers exist for the creation of rollovers.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/8/99
Returns:
TRUE if enough layers were defined to make a rollover FALSE otherwise

Definition at line 2390 of file slice.cpp.

02391 {
02392     INT32 i = 0;
02393     for (i = 0; i < 4; i++)
02394     {
02395         m_RolloverState[i].Exists = FALSE;
02396         m_RolloverState[i].pLayer = NULL;
02397         m_RolloverState[i].WasVisibleToStartWith = FALSE;
02398     }
02399 
02400     m_RolloverState[DEFAULT].Name.Load(_R(IDS_ROLLOVER_DEFAULT)); // = "Default";
02401     m_RolloverState[MOUSE].Name.Load(_R(IDS_ROLLOVER_MOUSE)); // = "Mouse";
02402     m_RolloverState[CLICKED].Name.Load(_R(IDS_ROLLOVER_CLICKED)); // = "Clicked";
02403     m_RolloverState[SELECTED].Name.Load(_R(IDS_ROLLOVER_SELECTED)); // = "Selected";
02404 
02405     Spread* pSelSpread = Document::GetSelectedSpread();
02406     if (pSelSpread == NULL)
02407         return FALSE;
02408 
02409     Layer * pLayer = pSelSpread->FindFirstLayer();
02410     while (pLayer)
02411     {
02412         for (i = 0; i < 4 ; i++)
02413         {
02414             if (pLayer->GetLayerID().CompareTo(m_RolloverState[i].Name) == 0)
02415             {
02416                 m_RolloverState[i].pLayer = pLayer;
02417                 m_RolloverState[i].WasVisibleToStartWith = pLayer->IsVisible();
02418 
02419                 // does this layer exist within the mosaic list?
02420                 m_RolloverState[i].Exists = FALSE;
02421 
02422                 // find a wix marker on this layer
02423                 Node * pNode = SliceHelper::FindNextOfClass(pLayer, pLayer, CC_RUNTIME_CLASS(TemplateAttribute) );
02424 
02425                 while (pNode/* && !m_RolloverState[i].Exists*/)
02426                 {
02427                     POSITION EachSlice = pMosaicList->GetHeadPosition();
02428 
02429                     // having found a marker does it match with any of the slices in the mosaic list?
02430                     while (EachSlice)
02431                     {
02432                         CSlice * pSlice = pMosaicList->GetNext(EachSlice);
02433                         if (pSlice->IsNamedSlice && pSlice->name.CompareTo(((TemplateAttribute *)pNode)->GetParam(), FALSE) == 0)
02434                         {
02435                             m_RolloverState[i].Exists = TRUE; // if it does than we need to export this state
02436                             pSlice->ExistsOnLayerState[i] = 1; // this slice exists on this state
02437                         }
02438                     }
02439 
02440                     pNode = SliceHelper::FindNextOfClass(pNode, pLayer, CC_RUNTIME_CLASS(TemplateAttribute) );
02441                 }
02442             }
02443         }
02444 
02445         pLayer = pLayer->FindNextLayer();
02446     }
02447 
02448     return (m_RolloverState[DEFAULT].Exists && 
02449             (m_RolloverState[MOUSE].Exists || m_RolloverState[CLICKED].Exists || m_RolloverState[SELECTED].Exists ));
02450     
02451 }

DocRect OpSlice::ScanLargeSliceBounds const String_256 Name  )  [static]
 

Definition at line 3066 of file slice.cpp.

03067 {
03068     DocRect Ret;
03069     Ret.MakeEmpty();
03070 
03071     // scan each layer
03072     Node * pTop = Document::GetSelectedSpread();
03073     Node * pNode = NULL;
03074     Node * pParent = NULL;
03075 
03076     if (pTop)
03077     {
03078         // scan from the first layer all through the layers since they are brothers of this layer
03079         pNode = SliceHelper::FindNextOfClass(pTop, pTop, CC_RUNTIME_CLASS(TemplateAttribute));
03080 
03081         while (pNode)
03082         {
03083             if (Name.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
03084             {
03085                 pParent = pNode->FindParent();
03086                 if (pParent->IsBounded())
03087                     Ret = Ret.Union(((NodeRenderableInk *)pParent)->GetBoundingRect(TRUE, FALSE));
03088             }
03089 
03090             pNode = SliceHelper::FindNextOfClass(pNode, pTop, CC_RUNTIME_CLASS(TemplateAttribute));
03091         }
03092     }
03093 
03094     return Ret;
03095 }

void OpSlice::ScanTextStorySliceBounds const String_256 Name,
DocRect Bounds
[protected]
 

Definition at line 3098 of file slice.cpp.

03099 {
03100     // scan each layer
03101     Node * pTop = Document::GetSelectedSpread();
03102     Node * pNode = NULL;
03103     Node * pParent = NULL;
03104     BOOL IncludesText = FALSE;
03105     DocRect TextModBounds;
03106 
03107     TextModBounds.MakeEmpty();
03108 
03109     if (pTop)
03110     {
03111         // scan from the first layer all through the layers since they are brothers of this layer
03112         pNode = SliceHelper::FindNextOfClass(pTop, pTop, CC_RUNTIME_CLASS(TemplateAttribute));
03113 
03114         while (pNode)
03115         {
03116             if (Name.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
03117             {
03118                 pParent = pNode->FindParent();
03119 
03120                 if (IS_A(pParent,TextChar) || IS_A(pParent,TextStory))
03121                 {
03122                     IncludesText= TRUE;
03123 
03124                     // expand the rect by the bounding rect of the text story / text char
03125                     // taking the intersection of the Metric method of size with the Bounding rect render method
03126                     // The metric assures us that the overall bounds of the rect will not be outside the
03127                     // complete scope of the text. The bounding rect method expands for ascenders and descenders
03128                     // only where they appear but may be too large as it includes visible onscreen UI.
03129                     // intersecting these two will easily give the correct answer 99.9% of the time
03130                     // and always a safe answer.
03131                     DocRect Temp = SliceHelper::BoundingNodeSize(pParent);
03132                     Temp = Temp.Intersection(((NodeRenderableInk *)pParent)->GetBoundingRect());
03133                     TextModBounds = TextModBounds.Union(Temp);
03134                 }
03135                 else // union in the usual way
03136                     TextModBounds = TextModBounds.Union(SliceHelper::BoundingNodeSize(pParent));
03137             }
03138 
03139             pNode = SliceHelper::FindNextOfClass(pNode, pTop, CC_RUNTIME_CLASS(TemplateAttribute));
03140         }
03141 
03142         if (IncludesText)
03143             Bounds = TextModBounds;
03144     }
03145 }

void OpSlice::ShowRolloverLayer INT32  ShowLayer  )  [protected]
 

Shows the layer number passed to it and hides the other of the rollover layers. Pass it DEFAULT, MOUSE, CLICKED, SELECTED, ORIGINAL_LAYERS or ALL_LAYERS.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/8/99

Definition at line 2513 of file slice.cpp.

02514 {
02515     Spread* pSelSpread = Document::GetSelectedSpread();
02516     if (pSelSpread == NULL)
02517         return;
02518 
02519     Layer * pLayer = pSelSpread->FindFirstLayer();
02520     while (pLayer)
02521     {
02522         INT32 i = 0;
02523         for (i = 0; i < 4 ; i++)
02524         {
02525             if (pLayer->GetLayerID().CompareTo(m_RolloverState[i].Name) == 0)
02526             {
02527                 if (ShowLayer == ORIGINAL_LAYERS /* Restore all layers to starting visibilty*/)
02528                     pLayer->SetVisible(m_RolloverState[i].WasVisibleToStartWith);
02529                 else
02530                 if (ShowLayer == ALL_LAYERS /* show all layers at once */)
02531                     pLayer->SetVisible(TRUE);
02532                 else
02533                 if (i == ShowLayer)
02534                     pLayer->SetVisible(TRUE);
02535                 else
02536                     pLayer->SetVisible(FALSE);
02537             }
02538         }
02539 
02540         pLayer = pLayer->FindNextLayer();
02541     }
02542 }

BOOL OpSlice::Slice CSlice pRect,
INT32  Ax,
INT32  Ay,
INT32  Bx,
INT32  By,
CList< CSlice *, CSlice * > *  pMosaicList
[protected]
 

Split the Slice pRect into smaller rectangles along the line AB.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/7/99
Returns:
TRUE if it performed a slice

Errors: On overlapped named slices

Definition at line 1101 of file slice.cpp.

01102 {
01103     if (!pRect->name.IsEmpty()) // Overlapping named slices
01104     {
01105         m_ErrorStr = pRect->name; // set the error string to be the name 
01106                                   // of the offending overlapping one
01107         return FALSE;
01108     }
01109 
01110     BOOL ok = FALSE;
01111     
01112     if (Ax == Bx) // Vert slice
01113     {
01114         pMosaicList->AddTail(new CSlice(pRect->left, pRect->top, Ax, pRect->bottom, "", m_PathName.GetType()));
01115         pMosaicList->AddTail(new CSlice(Ax, pRect->top, pRect->right, pRect->bottom, "", m_PathName.GetType()));
01116         ok = TRUE;
01117     }
01118     else
01119     if (Ay == By) // Horiz slice
01120     {
01121         pMosaicList->AddTail(new CSlice(pRect->left, pRect->top, pRect->right, Ay, "", m_PathName.GetType()));
01122         pMosaicList->AddTail(new CSlice(pRect->left, Ay, pRect->right, pRect->bottom, "", m_PathName.GetType()));
01123         ok = TRUE;
01124     }
01125     
01126     return ok;
01127 }

BOOL OpSlice::SortSlices CList< CSlice *, CSlice * > *  pMosaicList,
const DocRect Bounds
[protected]
 

Sorts the slices into order. Merges together suitable slices. Fills in colm & row positions, spans and width/heights for defining an HTML table. Gives names to nameless slices in the form r*c*.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/7/99
Returns:
FALSE if some error occured
WARNING *** Use of INT32_MIN assumes that the Slice rects and the DocRect/Spread coords that defined them are in the range of a INT32. This is a pretty safe asumption though

Definition at line 1300 of file slice.cpp.

01301 {
01302     POSITION ToDo = pMosaicList->GetHeadPosition();
01303 
01304     // go to Slice Co-ords from spread co-ords
01305     while (ToDo)
01306     {
01307         CSlice * pTopSlice = pMosaicList->GetNext(ToDo);
01308         pTopSlice->SwapSpreadAndSliceCoords();
01309     }
01310 
01311     // sort the Slices into order top left to bottom right
01312 
01313     ToDo = pMosaicList->GetHeadPosition();
01314 
01315     // ToDo moves through the whole mosaic list
01316     while (ToDo)
01317     {
01318         CSlice * pTopSlice = pMosaicList->GetNext(ToDo);
01319         POSITION Test = ToDo;
01320 
01321         // Test marks the iteration through the unsorted mosaic list
01322         // Is always between ToDo and the end of the list
01323         while (Test && !pTopSlice->deleteme)
01324         {
01325             CSlice * pTestSlice = pMosaicList->GetNext(Test);
01326 
01327             if (!pTestSlice->deleteme)
01328             {
01329                 BOOL merge = FALSE;
01330 
01331                 // test for merging the two rects together again
01332                 if (pTestSlice->name.IsEmpty() && pTopSlice->name.IsEmpty()) // don't merge selected rects!
01333                 {
01334                     // same height and y position
01335                     if (pTestSlice->top == pTopSlice->top && pTestSlice->bottom == pTopSlice->bottom)
01336                     {
01337                         if (pTestSlice->left == pTopSlice->right)
01338                         {
01339                             pTopSlice->right = pTestSlice->right;
01340                             merge = TRUE;
01341                         }
01342                         else if (pTestSlice->right == pTopSlice->left)
01343                         {
01344                             pTopSlice->left = pTestSlice->left;
01345                             merge = TRUE;
01346                         }
01347                     }
01348                     if (pTestSlice->left == pTopSlice->left && pTestSlice->right == pTopSlice->right)
01349                     {
01350                         if (pTestSlice->top == pTopSlice->bottom)
01351                         {
01352                             pTopSlice->bottom = pTestSlice->bottom;
01353                             merge = TRUE;
01354                         }
01355                         else if (pTestSlice->bottom == pTopSlice->top)
01356                         {
01357                             pTopSlice->top = pTestSlice->top;
01358                             merge = TRUE;
01359                         }
01360                     }
01361                 }
01362                 
01363                 if (merge)
01364                 {
01365                     //TRACE( _T("merged slices\n"));
01366                     // remove the test slice
01367                     // it has been absorbed
01368                     pTestSlice->deleteme = TRUE;
01369                 }
01370             }
01371         }
01372     }
01373 
01374     // delete marked slices
01375     ToDo = pMosaicList->GetHeadPosition();
01376 
01377     // Remove any slices marked for deletion
01378     // since they have been merged with another slice
01379     while (ToDo)
01380     {
01381         POSITION Test = ToDo;
01382         CSlice * pTestSlice = pMosaicList->GetNext(ToDo);
01383         if (pTestSlice->deleteme)
01384         {
01385             pMosaicList->RemoveAt(Test);
01386             delete pTestSlice;
01387         }
01388     }
01389 
01390 
01391 
01392     // sort the Slices into order top left to bottom right
01393 
01394     ToDo = pMosaicList->GetHeadPosition();
01395 
01396     // TopPosition == ToDo-1 marks the start of the unsorted mosaic list
01397     while (ToDo)
01398     {
01399         POSITION TopPosition = ToDo;
01400         CSlice * pTopSlice = pMosaicList->GetNext(ToDo);
01401         POSITION Test = ToDo;
01402 
01403 
01404         // LastTest == Test-1 marks the iteration through the unsorted mosaic list
01405         while (Test)
01406         {
01407             POSITION LastTest = Test;
01408             CSlice * pTestSlice = pMosaicList->GetNext(Test);
01409             
01410             // swap the two entries to sort them
01411             // ordering on the position of the top corner first
01412             // then if these are equal which is left most goes first
01413             if (pTestSlice->top < pTopSlice->top || 
01414             (pTestSlice->top == pTopSlice->top && pTestSlice->left < pTopSlice->left) )
01415             {
01416                 // swap the order of these two slices in the mosaic list
01417                 pMosaicList->SetAt(LastTest, pTopSlice);
01418                 pMosaicList->SetAt(TopPosition, pTestSlice);
01419 
01420                 // change what the top slice is for future compares
01421                 // during the lifetime of pTopSlice
01422                 pTopSlice = pTestSlice;
01423             }
01424         }
01425     }
01426 
01427     /*** WARNING *** Use of INT32_MIN assumes that the Slice rects and the DocRect/Spread coords
01428                      that defined them are in the range of a INT32.
01429                      This is a pretty safe asumption though */
01430     
01431     // set the row position
01432     INT32 LowestUnSetRow = INT32_MIN+1, LastLowestUnSetRow = INT32_MIN+1;
01433     INT32 RowHeight = 0;
01434     INT32 RowNumber = 1;
01435     while (LowestUnSetRow != INT32_MIN) 
01436     {
01437         // find the lowest unset row
01438         LowestUnSetRow = INT32_MIN;
01439         POSITION Test = pMosaicList->GetHeadPosition();
01440         while (Test)
01441             {
01442                 CSlice * pTestSlice = pMosaicList->GetNext(Test);
01443                 if (pTestSlice->row == -1 &&
01444                     (LowestUnSetRow == INT32_MIN || pTestSlice->top < LowestUnSetRow )
01445                     )
01446                 {
01447                     LowestUnSetRow = pTestSlice->top;
01448                 }
01449             }
01450 
01451         // calc the row height
01452         RowHeight = LowestUnSetRow - LastLowestUnSetRow;
01453         LastLowestUnSetRow = LowestUnSetRow;
01454 
01455         // set the lowest rows
01456         Test = pMosaicList->GetHeadPosition();
01457         while (Test)
01458             {
01459                 CSlice * pTestSlice = pMosaicList->GetNext(Test);
01460 
01461                 // set the row number if it hasn't been set and it is the lowest
01462                 if (pTestSlice->row == -1 && pTestSlice->top == LowestUnSetRow )
01463                 {
01464                     pTestSlice->row = RowNumber;
01465                     pTestSlice->rowheight = RowHeight;
01466                 }
01467 
01468                 // calculate the rows used by this slice
01469                 if (pTestSlice->top < LowestUnSetRow && pTestSlice->bottom > LowestUnSetRow /*&& pTestSlice->row != -1*/)
01470                 {
01471                     pTestSlice->rowspan++;
01472                 }
01473             }
01474         RowNumber ++;
01475     }
01476 
01477 
01478     // set the colm position    
01479     INT32 LowestUnSetColm = INT32_MIN + 1, LastLowestUnSetColm = Bounds.lox;
01480     INT32 ColmWidth = 0;
01481     INT32 ColmNumber = 1;
01482     while (LowestUnSetColm != INT32_MIN)
01483     {
01484         LowestUnSetColm = INT32_MIN;
01485         POSITION Test = pMosaicList->GetHeadPosition();
01486 
01487         // find the least left most point that doesn't have a set colm
01488         while (Test)
01489             {
01490                 CSlice * pTestSlice = pMosaicList->GetNext(Test);
01491                 if (pTestSlice->colm == -1 &&
01492                     (LowestUnSetColm == INT32_MIN || pTestSlice->left < LowestUnSetColm )
01493                     )
01494                 {
01495                     LowestUnSetColm = pTestSlice->left;
01496                 }
01497             }
01498 
01499         // calc the colm widths
01500         // extra bit of fiddling to get the last width by using the 
01501         // image bounding rect
01502         if (LowestUnSetColm != INT32_MIN)
01503             ColmWidth = (LowestUnSetColm - LastLowestUnSetColm);
01504         else
01505             ColmWidth = Bounds.hix - LastLowestUnSetColm;
01506 
01507         LastLowestUnSetColm = LowestUnSetColm;
01508 
01509         // Set the colm numbers
01510         Test = pMosaicList->GetHeadPosition();
01511         while (Test)
01512             {
01513                 CSlice * pTestSlice = pMosaicList->GetNext(Test);
01514 
01515                 // set the colm number if it hasn't been set and it is the lowest
01516                 if (pTestSlice->colm == -1 && pTestSlice->left == LowestUnSetColm )
01517                 {
01518                     pTestSlice->colm = ColmNumber;
01519                     pTestSlice->colmwidth = ColmWidth;
01520                     
01521                     // set the slice name if it doesn't have one
01522                     String_256 temp = "";
01523                     temp.MakeMsg(_R(IDS_SLICENAME), pTestSlice->row, pTestSlice->colm);
01524                     if (pTestSlice->name.IsEmpty())
01525                         pTestSlice->name = temp;
01526                 }
01527                 
01528                 // calculate the colms used by this slice
01529                 if (pTestSlice->left < LowestUnSetColm && pTestSlice->right > LowestUnSetColm /*&& pTestSlice->colm != -1*/)
01530                 {
01531                     pTestSlice->colmspan++;
01532                 }
01533             }
01534         ColmNumber ++;
01535     }
01536 
01537     
01538     // go from Slice Co-ords back to spread co-ords
01539     // so we can happily use a standard co-ord system again other places in Camelot
01540     m_NumberOfButtons = 0;
01541     ToDo = pMosaicList->GetHeadPosition();
01542     while (ToDo)
01543     {
01544         CSlice * pTestSlice = pMosaicList->GetNext(ToDo);
01545         pTestSlice->SwapSpreadAndSliceCoords();
01546 
01547         // and while we are here set the button number
01548         if (pTestSlice->IsNamedSlice)
01549         {
01550             m_NumberOfButtons++;
01551             pTestSlice->ButtonNumber = m_NumberOfButtons;
01552         }
01553     }
01554 
01555     return TRUE;
01556 }

INT32 OpSlice::TidyMosaicList CList< CSlice *, CSlice * > *  pMosaicList  )  [protected]
 

Deletes all the slices in the list now that we are done with them. So there will be no memory leeks.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/8/99

Definition at line 899 of file slice.cpp.

00900 {
00901     // tidy the mosaic list by deleting all its entries
00902     INT32 Pieces = 0;
00903     POSITION Test = pMosaicList->GetHeadPosition();
00904     while (Test)
00905         {
00906             CSlice * pTestSlice = pMosaicList->GetNext(Test);
00907             pMosaicList->RemoveHead();
00908             delete pTestSlice;
00909             Pieces++;
00910         }
00911 
00912     return Pieces;
00913 }

String_256 OpSlice::TurnUnderScoreIntoSpace const String_256 StartStr  )  [protected]
 

Definition at line 2575 of file slice.cpp.

02576 {
02577     INT32 i = 0;
02578 
02579     String_256 Str = StartStr;
02580 
02581     while (Str[i])
02582     {
02583         char stri = Str[i];
02584 
02585         if (stri == '_')
02586         {
02587             *((TCHAR *) Str +i) = (TCHAR)' ';
02588         }
02589 
02590         i++;
02591     }
02592 
02593     return Str;
02594 }

void OpSlice::UpdateSliceFileExts CList< CSlice *, CSlice * > *  pMosaicList  )  [protected]
 

Changes all non set file types to be the type the user picks from the file dlg.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/8/99

Definition at line 924 of file slice.cpp.

00925 {
00926     POSITION Test = pMosaicList->GetHeadPosition();
00927     while (Test)
00928         {
00929             CSlice * pTestSlice = pMosaicList->GetNext(Test);
00930             if (pTestSlice->FileTypeExtStr.CompareTo("non") == 0) // using non as a standard we haven't set this yet
00931                 pTestSlice->FileTypeExtStr = m_PathName.GetType();
00932         }
00933 
00934 }

BOOL OpSlice::URLScan String_256 pLinkName,
CList< CSlice *, CSlice * > *  pMosaicList
[protected]
 

Scans through the tree looking for URL tags. If it finds one it looks for a set name on the same node. If it finds a set name it scans the Mosaic list for the button with that set name and records the URL as the link name for that button number Param pMoasicList - List of the slices pLinkName - The dynamic array holding the URLs for each button Returns TRUE if it ran ok.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/12/99

Definition at line 2758 of file slice.cpp.

02759 {
02760     Spread* pSpread = Document::GetSelectedSpread();
02761     if (pSpread == NULL || pLinkName == NULL || pMosaicList == NULL)
02762         return FALSE;
02763 
02764     Node * pNode = SliceHelper::FindNextOfClass(pSpread, pSpread, CC_RUNTIME_CLASS(AttrWebAddress));
02765     while (pNode)
02766     {
02767         String_256 URL = ((AttrWebAddress *)pNode)->Value.m_url.GetWebAddress(); // the URL set from the URL dlg
02768         TCHAR* pTargetFrame = ((AttrWebAddress *)pNode)->Value.m_pcFrame; // ptr to the frame string set from the URL dlg
02769 
02770         Node *pWix = pNode->FindParent()->FindFirstChild();
02771         while (pWix)
02772         {
02773             if (pWix->IsAnAttribute() && IS_A(pWix,TemplateAttribute))
02774                 break;
02775             pWix = pWix->FindNext();
02776         }
02777 
02778         if (pWix)
02779         {
02780             POSITION ToDo = pMosaicList->GetHeadPosition();
02781             String_256 ButtonName = ((TemplateAttribute *)pWix)->GetParam();
02782 
02783             // do the mundge
02784             RemoveIlligalFileAndJavaChars(ButtonName);
02785 
02786             while (ToDo)
02787             {
02788                 CSlice * pSlice = pMosaicList->GetNext(ToDo);
02789 
02790                 if (pSlice->IsNamedSlice && pSlice->ButtonNumber > 0 && ButtonName.CompareTo(pSlice->name) == 0)
02791                 {
02792                     // no dot in the URL? Perhaps they mean a file name? Make it URL.htm (or.html) for them
02793                     if (URL.FindNextChar('.') == -1)
02794                     {
02795                         URL += ".";
02796                         URL += m_HTMLext;
02797                     }
02798 
02799                     // set this as the link name
02800                     pLinkName[pSlice->ButtonNumber - 1] = URL;
02801 
02802                     // set the target frame
02803                     pSlice->pFrameText = pTargetFrame;
02804                     pSlice->HasURL = TRUE;
02805 
02806                     ToDo = NULL;
02807                 }
02808             }
02809         }
02810 
02811         pNode = SliceHelper::FindNextOfClass(pNode, pSpread, CC_RUNTIME_CLASS(AttrWebAddress));
02812     }
02813 
02814     return TRUE;
02815 }

void OpSlice::WriteText ofstream &  f,
BYTE *  pData,
INT32  NoOfBytes
[static, protected]
 

There appeared to be a slight problem when using the write function to output text to the ofstream that contained chars 10 & 13. This function neatens this up cutting out 10,13 & 0 and putting a nice
in the right places. Param f - The output stream pData - the string to output NoOfBytes - Number of bytes to send to the stream Returns.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/2/00

Definition at line 2912 of file slice.cpp.

02913 {
02914     while (NoOfBytes)
02915     {
02916         INT32 scan = 0;
02917         BYTE * pTemp = pData;
02918         while (NoOfBytes && *pTemp != 10 && *pTemp != 13 && *pTemp != 0)
02919         {
02920             scan++;
02921             pTemp++;
02922             NoOfBytes--;
02923         }
02924 
02925         f.write(pData, scan);
02926         if (*pTemp != 0)
02927             f << "\n";
02928 
02929         pData = pTemp;
02930 
02931         while (NoOfBytes && (*pData == 10 || *pData == 13 || *pData == 0))
02932         {
02933             pData++;
02934             NoOfBytes--;
02935         }
02936     }
02937 }


Member Data Documentation

String_256 OpSlice::m_ErrorStr [protected]
 

Definition at line 227 of file slice.h.

BOOL OpSlice::m_ExportedHTMLOK [protected]
 

Definition at line 255 of file slice.h.

BOOL OpSlice::m_FoundRolloverStates [protected]
 

Definition at line 244 of file slice.h.

String_256 OpSlice::m_HTMLext [protected]
 

Definition at line 225 of file slice.h.

BOOL OpSlice::m_InjectHTML [protected]
 

Definition at line 256 of file slice.h.

INT32 OpSlice::m_lBlue [protected]
 

Definition at line 226 of file slice.h.

INT32 OpSlice::m_lGreen [protected]
 

Definition at line 226 of file slice.h.

INT32 OpSlice::m_lRed [protected]
 

Definition at line 226 of file slice.h.

INT32 OpSlice::m_NumberOfButtons [protected]
 

Definition at line 245 of file slice.h.

PathName OpSlice::m_PathName [protected]
 

Definition at line 224 of file slice.h.

String_256* OpSlice::m_pLinkName [protected]
 

Definition at line 238 of file slice.h.

RolloverState OpSlice::m_RolloverState[4] [protected]
 

Definition at line 243 of file slice.h.

BOOL OpSlice::m_UsedShimGraphic [protected]
 

Definition at line 229 of file slice.h.

BOOL OpSlice::m_UsesDesignNotes [protected]
 

Definition at line 231 of file slice.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:58:58 2007 for Camelot by  doxygen 1.4.4