bmpexprw.cpp

Go to the documentation of this file.
00001 // $Id: bmpexprw.cpp 1635 2006-08-01 13:09:47Z luke $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // A simple Dialog That does some Gavin Rendering into itself
00099 
00100 #include "camtypes.h"
00101 #include "bmpexprw.h"
00102 #include "prvwmenu.h" // the context menu for the dialog
00103 #include "ccdc.h"       // specific #includes needed for kernel-rendered dialogues
00104 #include "dlgcol.h"     // DialogColourInfo
00105 #include "grnddib.h"
00106 //#include "exprwres.h"
00107 #include "nodebmp.h"    // NodeBitmap
00108 #include "dlgview.h"    // DialogView
00109 #include "keypress.h"   // For Adjust key pressed test
00110 #include "csrstack.h"
00111 //#include "attr.h"     // for DM_EORPEN - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "fileutil.h"
00113 #include "bitfilt.h"    // the BaseBitmapFilter
00114 //#include "nev.h"
00115 //#include "tim.h"
00116 #include "statline.h"   // for the status line
00117 //#include "app.h"      // for Document - in camtypes.h [AUTOMATICALLY REMOVED]
00118 #include "giffiltr.h"   // for TI_GIFFilter
00119 #include "exjpeg.h"     // for JPEGExportFilter
00120 #include "imgmgkft.h"   // for ImageMagickFilter
00121 #include "progress.h"
00122 #include "sgliboil.h"
00123 #include "backgrnd.h"
00124 #include "bmpexdoc.h"
00125 #include "prvwflt.h"
00126 //#include "bmpreres.h"
00127 #include "bmapprev.h"
00128 //#include "accures.h"
00129 //#include "oilfltrs.h" // for find filter ext - in camtypes.h [AUTOMATICALLY REMOVED]
00130 #include "bitmpinf.h"   // for BitmapInfo
00131 
00132 DECLARE_SOURCE("$Revision: 1635 $");
00133 
00134 CC_IMPLEMENT_DYNCREATE(BitmapExportPreviewDialog, DialogOp)
00135 
00136 #define new CAM_DEBUG_NEW
00137 
00138 // define the fixed zoom factors (in percents) for click-zoom
00139 const UINT32 MIN_ZOOM = 1;
00140 const UINT32 MAX_ZOOM = 25601;
00141 const UINT32 ZOOMS[] = {MIN_ZOOM,10,25,50,75,100,200,500,1000,2000,4000,8000,16000,MAX_ZOOM};
00142 const INT32 NUM_ZOOMS = 14;
00143 
00144 // Set the static vars of the render dialog
00145 const CDlgMode BitmapExportPreviewDialog::Mode = MODELESS; //MODAL
00146 const UINT32 BitmapExportPreviewDialog::IDD = _R(IDD_BITMAPPREVIEWDIALOG);
00147 
00148 #define BUBBLE_TIME 800 
00149 
00150 /*******************************************************************************************
00151 ********************************************************************************************/
00152 // Initialise our statics
00153 
00154 BitmapExportPreviewDialog * BitmapExportPreviewDialog::m_pBitmapExportPreviewDialog = NULL;
00155 
00156 
00157 /*******************************************************************************************
00158 
00159 >   BitmapExportPreviewDialog::BitmapExportPreviewDialog() : DialogOp(RenderDlg::IDD, RenderDlg::Mode) 
00160 
00161     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
00162     Created:    11/4/97
00163     Purpose:    Constructs a Preview Dialog
00164 
00165 *******************************************************************************************/
00166 
00167 BitmapExportPreviewDialog::BitmapExportPreviewDialog(CWindowID ParentWnd)  
00168                                                         : DialogOp(BitmapExportPreviewDialog::IDD, 
00169                                                                     BitmapExportPreviewDialog::Mode, 
00170                                                                     0, CC_RUNTIME_CLASS(DialogOp), -1,
00171                                                                     ParentWnd) 
00172 {
00173     m_pBitmapExportPreviewDialog = this;
00174     
00175     m_pRender = NULL;
00176     m_Width = 1;
00177     m_Height = 1;
00178     m_CurrentPos.x = 0;
00179     m_CurrentPos.y = 0;
00180     m_CurrentTool = PREVIEW_PUSH_TOOL;
00181     m_Dragging = FALSE;
00182     m_ZoomRectRender = FALSE;
00183     m_CurID = -1;
00184     m_ActiveBitmap = 0;
00185 
00186 PORTNOTE("other","Removed BubbleHelp")
00187 //  m_LastCursorOverControlID = 0;
00188     m_BubbleHelpPending = TRUE;
00189     m_LastAdjustState = FALSE;
00190     m_MouseOperationStarted = FALSE;
00191     m_PreviousWithFocus = NULL;
00192     m_pBmpFilter = NULL;
00193     m_pParentDlg = NULL;
00194 
00195     m_Scaling = 1.0;
00196     m_ZoomFactor = 100.0;
00197     m_bWantCursorRedrawn = FALSE;
00198 
00199     pOriginalBitmap[0] = NULL;
00200     pOriginalBitmap[1] = NULL;
00201     m_bNeedBitmapCopied[0] = TRUE;
00202     m_bNeedBitmapCopied[1] = TRUE;
00203 }       
00204 
00205 
00206 
00207 /*******************************************************************************************
00208 
00209 >   BitmapExportPreviewDialog::~BitmapExportPreviewDialog()
00210 
00211     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
00212     Created:    11/4/97
00213     Purpose:    Destructor
00214 
00215 *******************************************************************************************/
00216 
00217 BitmapExportPreviewDialog::~BitmapExportPreviewDialog()
00218 {
00219     // clean out the render region, if allocated
00220     if (m_pRender)
00221     {
00222         // Delete the render region and its (dialog) view
00223         // Do it by hand as StopRender should have been called already
00224         delete m_pRender->GetRenderView();
00225         delete m_pRender;
00226 //      DestroyGRenderRegion(m_pRender);
00227         m_pRender = NULL;
00228     }
00229 
00230     // check for the same bitmap
00231     if (BitmapData[0].m_pBitmap == BitmapData[1].m_pBitmap)
00232     {
00233         // set the first object's flag so the common data gets deleted
00234         BitmapData[0].m_bIsSameBitmap = FALSE;
00235     }
00236 
00237     // delete the cursor if one is still left
00238     DeleteCurrentCursor();
00239     
00240 PORTNOTE("other","Removed BubbleHelp")
00241 #if !defined(EXCLUDE_FROM_XARALX)
00242     // if there is a bubble help window from a previous call, delete it
00243     if (m_pBubbleWnd != NULL)
00244     {
00245         delete m_pBubbleWnd;
00246         m_pBubbleWnd = NULL;
00247     }
00248 #endif
00249 
00250     // delete the background bitmap file, if one was created
00251     if (BitmapPreviewData::pPagePath != NULL)
00252     {
00253         FileUtil::DeleteFile(BitmapPreviewData::pPagePath);
00254         delete BitmapPreviewData::pPagePath;
00255         BitmapPreviewData::pPagePath = NULL;
00256     }
00257 
00258     // kill the static link to this dialog box
00259     m_pBitmapExportPreviewDialog = NULL;
00260 
00261     //  Get rid of the dynamically allocated KernelBitmap memory, if
00262     //  there has been any.
00263     if( pOriginalBitmap[0] )
00264     {
00265         delete pOriginalBitmap[0];
00266         pOriginalBitmap[0] = NULL; 
00267     }
00268     if( pOriginalBitmap[1] )
00269     {
00270         delete pOriginalBitmap[1];
00271         pOriginalBitmap[1] = NULL; 
00272     }
00273 
00274     // delete the non active export options but keep the active one
00275     // since the active one will be used outside this dlg
00276     // but the inactive one was stored by this dlg and used only here
00277     // See what is active by comparing it with the ptr to the one we
00278     // know we will use "BmapPrevDlg::m_pExportOptions"
00279     if (BitmapData[0].m_pOptions != BmapPrevDlg::m_pExportOptions && BitmapData[0].m_pOptions != NULL)
00280     {
00281         delete BitmapData[0].m_pOptions;
00282         BitmapData[0].m_pOptions = NULL;
00283     }
00284     if (BitmapData[1].m_pOptions != BmapPrevDlg::m_pExportOptions && BitmapData[1].m_pOptions != NULL)
00285     {
00286         delete BitmapData[1].m_pOptions;
00287         BitmapData[1].m_pOptions = NULL;
00288     }
00289 } 
00290 
00291 
00292 /***********************************************************************************************
00293 
00294 >   void FixZoomFactor (INT32 *pZoomFactor)
00295 
00296     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
00297     Created:    20/01/97
00298     Inputs:     pZoomFactor - a pointer to the zoom factor to be amended
00299     Purpose:    Searches the list of the pre-defined zoom factors for the one nearest to 
00300                 the current one. If the difference between them is less then 2% the current zoom 
00301                 factor is replaced by the pre-defined one. This is done to avoid things like 
00302                 zooming in from 99% to 100%, and also fixes problems with rounding errors
00303                 in the greater zoom factors.
00304     Returns:    None.
00305                                                                  
00306 ***********************************************************************************************/
00307 
00308 void FixZoomFactor (UINT32 *pZoomFactor)
00309 {
00310     UINT32 ZoomFactor = *pZoomFactor;
00311 
00312     if (ZoomFactor < MIN_ZOOM)
00313         *pZoomFactor = MIN_ZOOM;
00314     else
00315     if (ZoomFactor > ZOOMS[NUM_ZOOMS - 1])
00316         *pZoomFactor = ZOOMS[NUM_ZOOMS - 1];
00317     else
00318     for (INT32 i=0; i<NUM_ZOOMS; i++)
00319     {
00320         // the calculation is done times 1000 decause of the integer arithmetic
00321         INT32 Error = 50 * ZoomFactor;
00322         if ((1000 * ZoomFactor - Error  < 1000 * ZOOMS[i]) &&
00323             (1000 * ZoomFactor + Error  > 1000 * ZOOMS[i]))
00324         {
00325             *pZoomFactor = ZOOMS[i];
00326             return;
00327         }
00328     }
00329 }
00330 
00331 
00332 
00333 /***********************************************************************************************
00334 
00335 >   double CPluginWindow::FindNearestZoom(BOOL Up)
00336 
00337     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
00338     Created:    20/01/97
00339     Inputs:     Up  -   Indicates whether we are looking for zoom factor greater or smaller then 
00340                 the current one.
00341     Purpose:    Searches the list of the pre-defined zoom factors and finds the one nearest to 
00342                 the current one, but above it (Up == TRUE), or below it (Up = FALSE). Current 
00343                 zoom factor <= the smallest (10%) returns new zoom factor of 10%. Similarly 
00344                 current zoom factor <= the greatest(25601%) returns 25601
00345     Returns:    One of the pre-defined zoom factors.
00346                                                                  
00347 ***********************************************************************************************/
00348 
00349 double BitmapExportPreviewDialog::FindNearestZoom(BOOL Up)
00350 {
00351     UINT32 ZoomFactor;
00352 
00353     // get the zoom factor of the current bitmap
00354     if (m_ActiveBitmap == 1)
00355         ZoomFactor = (UINT32) m_ZoomFactor;
00356     else if (m_ActiveBitmap == 2)
00357         ZoomFactor = (UINT32) (m_ZoomFactor * m_Scaling);
00358     else
00359         return m_ZoomFactor;
00360 
00361     INT32 pos=NUM_ZOOMS - 1;
00362 
00363     // try to make it equal to one of the predefined zooms
00364     FixZoomFactor(&ZoomFactor);
00365 
00366     // find the position of the zoom factor in the list of predefined oness
00367     for (INT32 i=0;i<NUM_ZOOMS;i++)
00368         if (ZoomFactor <= ZOOMS[i])
00369         {
00370             // found a greater one, so remember the position
00371             pos=i;
00372             break;
00373         }
00374 
00375     if (Up)
00376     {
00377         // set it to the nearest one above it
00378         if ((ZoomFactor == ZOOMS[pos]) && (pos < NUM_ZOOMS - 1))
00379             ZoomFactor = ZOOMS[pos+1];
00380         else
00381             ZoomFactor = ZOOMS[pos];
00382     }
00383     else
00384     {
00385         // set it to the nearest one below it
00386         if (pos > 0)
00387             ZoomFactor = ZOOMS[pos-1];
00388         else
00389             ZoomFactor = ZOOMS[0];
00390     }
00391 
00392     // return a new value for the zoom factor, depending on the current bitmap
00393     if (m_ActiveBitmap == 2)
00394         return ZoomFactor / m_Scaling;
00395     else
00396         return ZoomFactor;
00397 }
00398 
00399 
00400 /*******************************************************************************************
00401 
00402 >   void BitmapExportPreviewDialog::DeleteCurrentCursor()
00403 
00404     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 
00405     Created:    07/5/97
00406     Purpose:    Sets the cursor depending on the current tool mode.
00407 
00408 *******************************************************************************************/
00409 
00410 void BitmapExportPreviewDialog::DeleteCurrentCursor()
00411 {
00412     // pop the cursor from the stack
00413     if (m_CurID != -1)
00414         delete CursorStack::GPop(m_CurID);
00415     m_CurID = -1;
00416 }
00417 
00418 
00419 /*******************************************************************************************
00420 
00421 >   void BitmapExportPreviewDialog::SetCurrentCursor(UINT32 id)
00422 
00423     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 
00424     Created:    07/5/97
00425     Inputs:     id - the IDof the control which asked for the cursor change
00426     Purpose:    Sets the cursor depending on the current tool mode and the control
00427 
00428 *******************************************************************************************/
00429 
00430 void BitmapExportPreviewDialog::SetCurrentCursor(UINT32 id)
00431 {
00432     // get he state of the Adjust(Shift) key    
00433     BOOL AdjustState = KeyPress::IsAdjustPressed();
00434 
00435     // if no change - return
00436     if ((m_CurID != -1) && (m_LastAdjustState == AdjustState))
00437     {
00438         //  Return, unless we want to have the cursor redrawn.
00439         if ( !m_bWantCursorRedrawn )
00440             return;
00441         else
00442             m_bWantCursorRedrawn = FALSE;
00443     }
00444 
00445     // remember the Adjust state
00446     m_LastAdjustState = AdjustState;
00447 
00448     // delete the old cursor
00449     DeleteCurrentCursor();
00450 
00451     Cursor *pCursor = NULL;
00452 
00453     // change the active bitmap if necessary
00454     if (((id == _R(IDC_REDRAW1)) && (m_ActiveBitmap != 1)) ||
00455         ((id == _R(IDC_REDRAW2)) && (m_ActiveBitmap != 2)))
00456     {
00457         // over the unselected control
00458         pCursor = new Cursor( wxCURSOR_ARROW );
00459     }
00460     else
00461     {
00462         // set the proper cursor
00463         if (m_CurrentTool == PREVIEW_ZOOM_TOOL)
00464         {
00465             if (AdjustState)
00466                 pCursor = new Cursor( (Tool_v1*)NULL, _R(IDC_ZOOMOUT));
00467             else
00468                 pCursor = new Cursor( (Tool_v1*)NULL, _R(IDC_ZOOMIN));
00469         }
00470         else if (m_CurrentTool == PREVIEW_PUSH_TOOL)
00471         {
00472             pCursor = new Cursor( (Tool_v1*)NULL, _R(IDC_PICKHAND));
00473         }                                   
00474         else if( m_CurrentTool == PREVIEW_COLOUR_SELECTOR_TOOL )
00475         {
00476             //  Set the cursor for the colour selector. 
00477             pCursor = new Cursor( (Tool_v1*)NULL, _R(IDC_COLOURSELECTOR) );
00478         }
00479         else
00480             pCursor = new Cursor( (Tool_v1*)NULL, _R(IDC_COLOURSELECTOR) );
00481     }
00482     
00483     // push (and display) the cursor
00484     m_CurID = CursorStack::GPush(pCursor);
00485 }
00486 
00487 
00488 
00489 
00490 /*******************************************************************************************
00491 
00492 >   void BitmapExportPreviewDialog::ResetInfo(UINT32 id)
00493 
00494     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 
00495     Created:    07/5/97
00496     Inputs:     id - the ID of the control the mouse is over
00497     Purpose:    Resets the bubble help system and displays status text for the control the 
00498                 mouse is over. Called on a mouse operation.
00499 
00500 *******************************************************************************************/
00501 
00502 void BitmapExportPreviewDialog::ResetInfo(UINT32 id)
00503 {
00504     // if we've moved since the last time
00505     if (id != m_LastCursorOverControlID)
00506     {
00507         // start the timer for the bubble help
00508         BubbleTimer.Sample();
00509         
00510         // remember the control the mouse is over
00511         m_LastCursorOverControlID = id;
00512 
00513 PORTNOTE("other","Removed BubbleHelp")
00514 #if !defined(EXCLUDE_FROM_XARALX)
00515         // delete the bubble help window
00516         delete m_pBubbleWnd;
00517         m_pBubbleWnd = NULL;
00518 #endif
00519 
00520         m_BubbleHelpPending = TRUE;
00521 
00522         // now do the status line messages
00523         
00524         UINT32 StatusTextID = 0;        
00525         // find the status text ID from the Gadget ID
00526         if( id == _R(IDC_ZOOM_TOOL) )
00527             StatusTextID = _R(IDS_ZOOM_TOOL_STATUS_TEXT);
00528         else
00529         if( id == _R(IDC_PUSH_TOOL) )
00530             StatusTextID = _R(IDS_PUSH_TOOL_STATUS_TEXT);
00531         else
00532         if( id == _R(IDC_ZOOM_TO_FIT) )
00533             StatusTextID = _R(IDS_ZOOMTOFIT_STATUS_TEXT);
00534         else
00535         if( id == _R(IDC_100PERCENT) )
00536             StatusTextID = _R(IDS_ZOOMTO100_STATUS_TEXT);
00537         else
00538         if( id == _R(IDC_1TO1) )
00539             StatusTextID = _R(IDS_1TO1_STATUS_TEXT);
00540         else
00541         if( id == _R(IDC_COLOUR_SELECTOR) )
00542             StatusTextID = _R(IDS_COLOUR_SELECTOR_STATUS_TEXT);
00543         else
00544         if( id == _R(IDC_REDRAW1) ||
00545             id == _R(IDC_REDRAW2) )
00546         {
00547             // over one of the draw controls
00548 
00549             if (((id == _R(IDC_REDRAW1)) && (m_ActiveBitmap != 1)) ||
00550                 ((id == _R(IDC_REDRAW2)) && (m_ActiveBitmap != 2)))
00551             {
00552                 // over the unselected bitmap
00553                 StatusTextID = _R(IDS_UNSELECTED_STATUS_TEXT);
00554             }
00555             else
00556             {
00557                 // over the selected bitmap - display the current tool options
00558                 if (m_CurrentTool == PREVIEW_ZOOM_TOOL)
00559                     StatusTextID = _R(IDS_ZOOM_MODE_STATUS_TEXT);
00560                 else if (m_CurrentTool == PREVIEW_PUSH_TOOL)
00561                     StatusTextID = _R(IDS_PUSH_MODE_STATUS_TEXT);
00562                 else if( m_CurrentTool == PREVIEW_COLOUR_SELECTOR_TOOL )
00563                     StatusTextID = _R(IDS_COLOUR_SELECTOR_MODE_STATUS_TEXT);
00564             }
00565         }
00566         else
00567             StatusTextID = _R(IDS_BITMAPPREVIEWDIALOG);
00568         
00569         // put up some status line help
00570         StatusLine* pStatusLine=GetApplication()->GetpStatusLine();
00571         if (pStatusLine != NULL)
00572         {
00573             String_256  str( StatusTextID );
00574             pStatusLine->UpdateText( &str, FALSE );
00575         }
00576     }
00577 }
00578 
00579 
00580 
00581 
00582 /********************************************************************************************
00583 
00584 >   void BitmapExportPreviewDialog::DoBubbleHelp()
00585 
00586     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
00587     Created:    10/5/97
00588     Inputs:     -
00589     Outputs:    -
00590     Returns:    -
00591     Purpose:    Displays bubble help (if any) for the control the mouse is over
00592 
00593 ********************************************************************************************/
00594 
00595 void BitmapExportPreviewDialog::DoBubbleHelp()
00596 {
00597 PORTNOTE("other","Removed BubbleHelp")
00598 #if !defined(EXCLUDE_FROM_XARALX)
00599     // if there is a bubble help window from a previous call, delete it
00600     if (m_pBubbleWnd != NULL)
00601     {
00602         delete m_pBubbleWnd;
00603         m_pBubbleWnd = NULL;
00604     }
00605 #endif
00606     
00607     // check if we are over a control
00608     if (!m_LastCursorOverControlID)
00609         return;
00610 
00611     UINT32 BubbleID = 0;
00612 
00613     // find the bubble text ID from the Gadget ID
00614     if( m_LastCursorOverControlID == _R(IDC_ZOOM_TOOL) )
00615         BubbleID = _R(IDS_PREVIEW_ZOOM_TOOL);
00616     else
00617     if( m_LastCursorOverControlID == _R(IDC_PUSH_TOOL) )
00618         BubbleID = _R(IDS_PREVIEW_PUSH_TOOL);
00619     else
00620     if( m_LastCursorOverControlID == _R(IDC_ZOOM_TO_FIT) )
00621         BubbleID = _R(IDS_PREVIEW_ZOOM_TO_FIT);
00622     else
00623     if( m_LastCursorOverControlID == _R(IDC_100PERCENT) )
00624         BubbleID = _R(IDS_PREVIEW_ZOOM_TO_100);
00625     else
00626     if( m_LastCursorOverControlID == _R(IDC_1TO1) )
00627         BubbleID = _R(IDS_PREVIEW_1TO1);
00628     else
00629     if( m_LastCursorOverControlID == _R(IDC_COLOUR_SELECTOR) )
00630         BubbleID = _R(IDS_PREVIEW_COLOUR_SELECTOR);
00631     else
00632         m_LastCursorOverControlID = 0;
00633 
00634     // no bubble found
00635     if (BubbleID == 0)
00636         return;
00637     
00638 PORTNOTE("other","Removed BubbleHelp")
00639 #ifndef EXCLUDE_FROM_XARALX
00641     String_256 BubbleText(BubbleID);
00642 
00643     // Make a new bubble help window
00644     try
00645     {
00646         m_pBubbleWnd = new BubbleHelpWnd;
00647     }
00648     catch( CMemoryException )
00649     {
00650         TRACEALL( _T("Unable to create bubble help window!\n"));
00651         return;
00652     }
00653 
00654     // Create the actual window
00655     if (!m_pBubbleWnd->Create())
00656     {
00657         TRACEALL( _T("Could not Init bubble help window\n"));
00658         return;
00659     }
00660 
00661     // set the text
00662     if (!m_pBubbleWnd->SetText(BubbleText))
00663         return;  // no bubble help for this item
00664 
00665     // display the window
00666     m_pBubbleWnd->Show();
00667 #endif
00668 }
00669 
00670 
00671 /*******************************************************************************************
00672 
00673 >   MsgResult BitmapExportPreviewDialog::Message(Msg* Message)
00674 
00675     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
00676     Created:    11/4/97
00677     Purpose:    Handles all the Preview dialog's messages 
00678 
00679 *******************************************************************************************/
00680 MsgResult BitmapExportPreviewDialog::Message(Msg* Message)
00681 {
00682     // See if it is for us
00683     if (IS_OUR_DIALOG_MSG(Message))
00684     {
00685         // it is
00686         DialogMsg* Msg = (DialogMsg*)Message;
00687 
00688         // Main handler for dialog type messages
00689         BOOL EndDialog = FALSE;                     // TRUE if we should quit the dialog
00690 
00691         // decide what to do
00692         switch (Msg->DlgMsg)
00693         {
00694             // Create message
00695             case DIM_CREATE:
00696             {
00697                 // Force the arrow cursor on to the top of the cursor stack
00698                 m_TopLevelCursor = CursorStack::GPush(Cursor::Arrow);
00699 
00700                 // As it is a modal dialog box we are sent a message to say the dialog box
00701                 // is being created, so we have a chance to set the initial control values.
00702                 if (Mode == MODAL)
00703                     InitDialog();
00704 
00705                 // set up the timer
00706                 SetTimer(1000,100);
00707 
00708                 break;
00709             }
00710 
00711             // Close and destroy the dialog 
00712             case DIM_COMMIT:
00713             case DIM_CANCEL:
00714             {
00715                 // remove the allocated cursor
00716                 DeleteCurrentCursor();
00717 
00718                 CursorStack::GPop(m_TopLevelCursor);
00719 
00720                 KillTimer(1000);
00721 
00722                 // delete the unused disk file
00723                 if ((m_ActiveBitmap == 1) || (m_ActiveBitmap == 2))
00724                 {
00725                     // delete the temp file for the non-active bitmap
00726                     if (BitmapData[2-m_ActiveBitmap].m_bIsSameBitmap != TRUE) // not same bitmap
00727                     {
00728                         // delete the file
00729                         PathName    path( BitmapData[2-m_ActiveBitmap].m_pOptions->GetPathName() );
00730                         FileUtil::DeleteFile( & path );
00731                     }
00732 
00733                     // delete the temp file for the active bitmap, but only if Cancel was chosen
00734                     if (Msg->DlgMsg == DIM_CANCEL)
00735                     {
00736                         PathName    path( BitmapData[m_ActiveBitmap-1].m_pOptions->GetPathName() );
00737                         FileUtil::DeleteFile( &path );
00738                     }
00739                 }
00740 
00741 PORTNOTE("other","Removed BubbleHelp")
00742 #if !defined(EXCLUDE_FROM_XARALX)
00743                 // if there is a bubble help window from a previous call, delete it
00744                 if (m_pBubbleWnd != NULL)
00745                 {
00746                     delete m_pBubbleWnd;
00747                     m_pBubbleWnd = NULL;
00748                 }
00749 #endif
00750 
00751                 EndDialog = TRUE;
00752                 //Close();
00753                 //End();
00754                 break;
00755             }
00756 
00757             case DIM_TIMER:
00758             {
00759                 // check for bubble help pending
00760                 if (m_BubbleHelpPending)
00761                     if (BubbleTimer.Elapsed(BUBBLE_TIME))
00762                     {
00763                         m_BubbleHelpPending = FALSE;
00764                         DoBubbleHelp();
00765                     }
00766                 break;
00767             }
00768 
00769             case DIM_LFT_BN_DOWN :
00770             {
00771                 if( Msg->GadgetID == _R(IDC_REDRAW1) ||
00772                     Msg->GadgetID == _R(IDC_REDRAW2) )
00773                 {
00774                     // get the extra info
00775                     ReDrawInfoType*param = (ReDrawInfoType*) Msg->DlgMsgParam;
00776                     
00777                     // sanity check
00778                     ERROR3IF((param == NULL)  || (param->pMousePos == NULL), "Invalid mouse position passed");
00779                         
00780                     // remember the current pos
00781                     m_CurrentPos = *(param->pMousePos);
00782 
00783                     // initialize for zoom to rect
00784                     m_StartPos = m_CurrentPos;
00785 
00786                     // indicate start of mouse operation
00787                     m_MouseOperationStarted = TRUE;
00788 
00789                     //  If we are doing image slicing, then return now
00790                     if( BmapPrevDlg::m_bSlicingImage )
00791                         break;
00792 
00793                     // If the 'Colour Selector' is selected, the file format supports a palette
00794                     // and the message is for the active window more things have to be done.
00795                     if( m_CurrentTool == PREVIEW_COLOUR_SELECTOR_TOOL &&
00796                         m_pParentDlg->m_pExportOptions->GetSupportsPalette() &&
00797                         (
00798                             ((Msg->GadgetID==_R(IDC_REDRAW1)) && (m_ActiveBitmap==1)) ||
00799                             ((Msg->GadgetID==_R(IDC_REDRAW2)) && (m_ActiveBitmap==2))
00800                         ) )
00801                     {
00802                         //  The user has just clicked on a pixel in one of the preview images
00803                         //  Need to get the palette inidex of the colour that this pixel uses.
00804                         INT32 PaletteIndex = GetPaletteIndexOfColour( param, Msg->GadgetID );
00805                         //  If -1 was returned, then something went wrong, so just leave.
00806                         if( PaletteIndex == -1 )
00807                             break;
00808                         m_pParentDlg->SetPaletteSelection(PaletteIndex);
00809                     }
00810                 }
00811                 break;
00812             }
00813 
00814 
00815             case DIM_LFT_BN_UP :
00816             {
00817                 if( Msg->GadgetID == _R(IDC_REDRAW1) ||
00818                     Msg->GadgetID == _R(IDC_REDRAW2) )
00819                 {
00820                     // if the press of the button was outside the control, or ESC was pressed
00821                     if (!m_MouseOperationStarted)
00822                     {                       
00823                         // delete the cursor so new one can be displayed
00824                         DeleteCurrentCursor();
00825 
00826                         break;
00827                     }
00828                         
00829                     // end of the mouseop
00830                     m_MouseOperationStarted = FALSE;
00831 
00832                     // change the active bitmap if necessary
00833                     if (((Msg->GadgetID == _R(IDC_REDRAW1)) && (m_ActiveBitmap != 1)) ||
00834                         ((Msg->GadgetID == _R(IDC_REDRAW2)) && (m_ActiveBitmap != 2)))
00835                     {
00836                         // change the selected bitmap
00837                         ChangeActiveBitmap(1 + (m_ActiveBitmap == 1));
00838                     }
00839                     else
00840                     {
00841                         //perform zoom/pan
00842 
00843                         // get the extra info
00844                         ReDrawInfoType*param = (ReDrawInfoType*) Msg->DlgMsgParam;
00845                             
00846                         // sanity check
00847                         ERROR3IF((param == NULL)  || (param->pMousePos == NULL), 
00848                                                 "Invalid mouse position passed");
00849                             
00850                         // remember the current position
00851                         m_CurrentPos = *(param->pMousePos);
00852 
00853                         if (m_CurrentTool == PREVIEW_ZOOM_TOOL)
00854                         {
00855                             if (!m_Dragging) // click-zoom
00856                                 CalcViewRect(FindNearestZoom(!KeyPress::IsAdjustPressed()),
00857                                         param->pMousePos);
00858                             else // zoom to rectangle
00859                                     ZoomToRect();
00860                         }
00861 
00862                         m_Dragging = FALSE;
00863                     }
00864     
00865                     // delete the cursor so new one can be displayed
00866                     DeleteCurrentCursor();
00867 
00868                 }
00869                 else
00870                 // Any other controls on the 1st image, swap to that image
00871                 if( Msg->GadgetID == _R(IDC_ACTIVE1) ||
00872 //                  case _R(IDC_ACTIVEFRAME1) :
00873                     Msg->GadgetID == _R(IDC_IMAGESIZE1) ||
00874                     Msg->GadgetID == _R(IDC_FILESIZE1) ||
00875                     Msg->GadgetID == _R(IDC_FILEDIFF1) ||
00876                     Msg->GadgetID == _R(IDC_FILE_TYPE_LIST) )
00877                 {
00878                     // change the active bitmap if necessary
00879                     if (m_ActiveBitmap != 1)
00880                     {
00881                         // change the selected bitmap
00882                         ChangeActiveBitmap(1 + (m_ActiveBitmap == 1));
00883                         //  Don't want to respond to any mouse messages until this piece has
00884                         //  been finished. 
00885 //                      m_pParentDlg->SetDontWantMouseMessage( TRUE );
00886 //                      BmapPrevDlg::m_bNeedPaletteUpdated = TRUE;
00887                     }
00888                 }
00889                 else
00890                 // Any other controls on the second image, swap to that image
00891                 if( Msg->GadgetID == _R(IDC_ACTIVE2) ||
00892 //                  case _R(IDC_ACTIVEFRAME2) :
00893                     Msg->GadgetID == _R(IDC_ACTIVE2) || Msg->GadgetID == _R(IDC_IMAGESIZE2) ||
00894                     Msg->GadgetID == _R(IDC_ACTIVE2) || Msg->GadgetID == _R(IDC_FILESIZE2) ||
00895                     Msg->GadgetID == _R(IDC_ACTIVE2) || Msg->GadgetID == _R(IDC_FILEDIFF2) ||
00896                     Msg->GadgetID == _R(IDC_ACTIVE2) || Msg->GadgetID == _R(IDC_FILE_TYPE_LIST2) )
00897                 {
00898                     // change the active bitmap if necessary
00899                     if (m_ActiveBitmap != 2)
00900                     {
00901                         // change the selected bitmap
00902                         ChangeActiveBitmap(1 + (m_ActiveBitmap == 1));
00903                     }
00904                 }
00905                 break;
00906             }
00907 
00908             case DIM_MOUSE_MOVE :
00909             {
00910                 ResetInfo(Msg->GadgetID);
00911                 
00912                 if (Msg->GadgetID != _R(IDC_REDRAW1) && Msg->GadgetID != _R(IDC_REDRAW2))
00913                 {
00914                     DeleteCurrentCursor();                  // pop the cursor from the stack
00915                     ReleaseMouse(Msg->GadgetID);            // release the mouse capture
00916                     if (m_PreviousWithFocus != NULL)        // restore the keyboard input focus to
00917                         m_PreviousWithFocus->SetFocus();    // the last window with the focus
00918                     m_PreviousWithFocus = NULL; // reset it
00919                 }
00920                 else
00921                 {
00922                     // mouse move messages are handled only so that we can capture 
00923                     // the mouse. This also allows us to set a cursor, because the  
00924                     // cursor doesn't get displayed, when the window is not a top one, 
00925                     // unless the mouse is captured. Thus by capturing the mouse
00926                     // we can both check for the mouse pointer inside the control
00927                     // and set the proper cursor.
00928                     
00929                     // get the extra info
00930                     ReDrawInfoType*param = (ReDrawInfoType*) Msg->DlgMsgParam;
00931                     
00932                     // sanity check
00933                     ERROR3IF((param == NULL)  || (param->pMousePos == NULL), 
00934                         "Invalid mouse position passed");
00935                     
00936                     // if the mouse leaves the control, release the capture
00937                     if ((param->pMousePos->x < 0) || (param->pMousePos->x > param->dx) ||
00938                         (param->pMousePos->y < 0) || (param->pMousePos->y > param->dy))
00939 
00940                     {
00941                         // release the mouse capture
00942                         ReleaseMouse(Msg->GadgetID);
00943                         
00944                         // restore the keyboard input focus to the last window with the focus
00945                         if (m_PreviousWithFocus != NULL)
00946                             m_PreviousWithFocus->SetFocus();
00947                         m_PreviousWithFocus = NULL; // reset it
00948                         
00949                         // pop the cursor from the stack
00950                         DeleteCurrentCursor();
00951                     }
00952                     else
00953                     {
00954 PORTNOTE("other","Removed some oilieness for kernel")
00955 #ifndef EXCLUDE_FROM_XARALX
00956                         // get the hwnd of the control
00957                         CWindowID hChild = ::GetDlgItem(GetReadWriteWindowID(), Msg->GadgetID);
00958                         
00959                         // set the keyboard input focus to our control
00960                         HWND hWnd = ::SetFocus(hChild);
00961                         
00962                         // remember the last window with the focus
00963                         if (m_PreviousWithFocus == NULL)
00964                             m_PreviousWithFocus = hWnd; 
00965                         
00966                         //capture the mouse pointer
00967                         CaptureMouse(Msg->GadgetID);
00968 #endif
00969                         // the mouse is moved inside the control, so update the cursor
00970                         SetCurrentCursor(Msg->GadgetID);
00971                         
00972                         //  If we are doing image slicing, then return now
00973                         if( BmapPrevDlg::m_bSlicingImage )
00974                             break;
00975                         
00976                         //  If the 'Colour Selector' is selected, then some more things have to be done.
00977                         if( m_CurrentTool == PREVIEW_COLOUR_SELECTOR_TOOL &&
00978                             m_pParentDlg->m_pExportOptions->GetSupportsPalette() &&
00979                             (
00980                             ((Msg->GadgetID==_R(IDC_REDRAW1)) && (m_ActiveBitmap==1)) ||
00981                             ((Msg->GadgetID==_R(IDC_REDRAW2)) && (m_ActiveBitmap==2))
00982                             )
00983                             )
00984                         {
00985                             //  The user has just clicked on a pixel in one of the preview images
00986                             //  Need to get the palette index of the colour that this pixel uses.
00987                             INT32 PaletteIndex = GetPaletteIndexOfColour( param, Msg->GadgetID );
00988 
00989                             if( PaletteIndex != -1 )
00990                                 m_pParentDlg->SetPaletteHighlight(PaletteIndex);
00991                         }
00992                     }
00993                 }
00994                 break;
00995             }
00996 
00997             case DIM_MOUSE_DRAG :
00998             {
00999                 ResetInfo(Msg->GadgetID);
01000 
01001                 if( Msg->GadgetID == _R(IDC_REDRAW1) ||
01002                     Msg->GadgetID == _R(IDC_REDRAW2) )
01003                 {
01004                     // check whether the mouse button was first pressed inside our window
01005                     if (!m_MouseOperationStarted)
01006                         break;
01007 
01008                     // check for a drag in the unselected control
01009                     if (((Msg->GadgetID == _R(IDC_REDRAW1)) && (m_ActiveBitmap != 1)) ||
01010                         ((Msg->GadgetID == _R(IDC_REDRAW2)) && (m_ActiveBitmap != 2)))
01011                         break;
01012 
01013                     if (KeyPress::IsEscapePressed())
01014                     {
01015                         // cancel the operation
01016                         m_MouseOperationStarted = FALSE;
01017                     
01018                         // if we are zooming to a rectangle, hide the rectangle
01019                         if (m_Dragging && (m_CurrentTool == PREVIEW_ZOOM_TOOL))
01020                             DrawZoomRect();
01021                     }
01022                     else
01023                     {
01024                         // get the extra info
01025                         ReDrawInfoType*param = (ReDrawInfoType*) Msg->DlgMsgParam;
01026                         
01027                         // sanity check
01028                         ERROR3IF((param == NULL)  || (param->pMousePos == NULL), "Invalid mouse position passed");
01029                         
01030                         m_Dragging = TRUE;
01031 
01032                         // put up some status line help
01033                         StatusLine* pStatusLine=GetApplication()->GetpStatusLine();
01034                         if (pStatusLine != NULL)
01035                         {
01036                             UINT32 StatusTextID= 0;
01037                             if (m_CurrentTool == PREVIEW_PUSH_TOOL)
01038                                 StatusTextID = _R(IDS_PUSH_DRAG_STATUS_TEXT);
01039                             else if (m_CurrentTool == PREVIEW_ZOOM_TOOL)
01040                                 StatusTextID = _R(IDS_ZOOM_DRAG_STATUS_TEXT);
01041 
01042                             // display the text
01043                             if (StatusTextID != 0)
01044                             {
01045                                 String_256  str( StatusTextID );
01046                                 pStatusLine->UpdateText( &str, FALSE );
01047                             }
01048                         }
01049 
01050                         // perform the drag operation
01051                         if (m_CurrentTool == PREVIEW_PUSH_TOOL)
01052                             DoPush(param->pMousePos);
01053                         else if (m_CurrentTool == PREVIEW_ZOOM_TOOL)
01054                             DoZoom(param->pMousePos);
01055                     }
01056                 }
01057                 break;
01058             }
01059 
01060         case DIM_RGT_BN_UP :
01061             {
01062                 // See which button was pressed
01063                 if( Msg->GadgetID == _R(IDC_REDRAW1) ||
01064                     Msg->GadgetID == _R(IDC_REDRAW2) )
01065                 {
01066                     // change the active bitmap if necessary
01067                     if (((Msg->GadgetID == _R(IDC_REDRAW1)) && (m_ActiveBitmap != 1)) ||
01068                         ((Msg->GadgetID == _R(IDC_REDRAW2)) && (m_ActiveBitmap != 2)))
01069                     {
01070                         // change the selected bitmap
01071                         ChangeActiveBitmap(1 + (m_ActiveBitmap == 1));
01072 //                      BmapPrevDlg::m_bNeedPaletteUpdated = TRUE;
01073                     }
01074                     else
01075                     {
01076                         // initialise the popup menu
01077                         OpPreviewPopupCommand::Init();
01078                         // create the right-click menu
01079                         PreviewContextMenu *menu = new PreviewContextMenu;
01080 
01081                         // display the menu
01082                         if (menu != NULL)
01083                             menu->Show();
01084                         else
01085                             ERROR3("Can't create PreviewContextMenu");
01086                     }
01087 
01088                     // delete the cursor, so new one can be set
01089                     DeleteCurrentCursor();
01090                 }
01091                 break;
01092             }
01093 
01094         
01095         case DIM_LFT_BN_CLICKED :
01096             {
01097                 // See which button was pressed
01098                 if( Msg->GadgetID == _R(IDC_ZOOM_TOOL) )
01099                     OnZoomTool();
01100                 else
01101                 if( Msg->GadgetID == _R(IDC_PUSH_TOOL) )
01102                     OnPushTool();
01103                 else
01104                 if( Msg->GadgetID == _R(IDC_ZOOM_TO_FIT)  )
01105                 {
01106                     // first check if there is any bitmap
01107                     if (m_ActiveBitmap != 0)
01108                         CalcViewRect(-1, NULL);
01109                 }
01110                 else
01111                 if( Msg->GadgetID == _R(IDC_1TO1) )
01112                     On1to1();
01113                 else
01114                 if( Msg->GadgetID == _R(IDC_100PERCENT) )
01115                     On100Percent();
01116                 else
01117                 if( Msg->GadgetID == _R(IDC_COLOUR_SELECTOR) )
01118                     OnColourSelectorTool();
01119                 
01120                 break;
01121             }
01122 
01123             case DIM_REDRAW :
01124             {
01125                 // This is where all the redrawing is done
01126                 // Which control in the window is sending the redraw message (if there are many
01127                 // grdraw controls you can tell which is which from the Gadget ID
01128 
01129                 // Draw the redraw_me control in here
01130                 if( Msg->GadgetID == _R(IDC_REDRAW1) ||
01131                     Msg->GadgetID == _R(IDC_REDRAW2) )
01132                 {
01133                     RenderControl((ReDrawInfoType*) Msg->DlgMsgParam, Msg->GadgetID);
01134                 }
01135                 else
01136                 {
01137                     // there are no other controls that should get a redraw message ever
01138                 
01139                     // give out an error in debug builds, ignore in retail builds
01140                     ERROR3("Got a redraw message for a control I don't know about");
01141                 }
01142 
01143                 break;
01144             }
01145 
01146             //  The user made a selection from one of the file type drop-lists
01147             case DIM_SELECTION_CHANGED:
01148             {
01149                 //  Make sure that the message came from one of the file type drop-lists
01150                 //  before calling the handling function.
01151                 if( Msg->GadgetID == _R(IDC_FILE_TYPE_LIST) )   
01152                     HandleFileTypeListChange( 0 );
01153                 else
01154                 if( Msg->GadgetID == _R(IDC_FILE_TYPE_LIST2) )
01155                     HandleFileTypeListChange( 1 );
01156 
01157                 break;
01158             }
01159 
01160             default:
01161                 // Do nothing, but quiten compiler
01162                 break;
01163         }
01164 
01165         // Allow the base class access to the message, it will do the
01166         // DLG_EAT_IF_HUNGRY(Msg) for us
01167         // Must do this before the Close and End
01168         MsgResult Result = DialogOp::Message(Message);
01169 
01170         // End dialog here
01171         if (EndDialog) 
01172         {
01173             // DialogOp has already done this
01174 //          Close();                // Hide the dialog box
01175 //          End();                  // Finish the operation
01176 
01177             // Free up any unused bitmaps in the global list
01178             // (just deleting the KernelBitmaps doesn't seem to do it)
01179             Camelot.GetGlobalBitmapList()->DeleteAllUnusedBitmaps();
01180         }
01181         
01182         // Return
01183         // The message was for our dialog box so return that we have handled it, if necessary
01184         //return (DLG_EAT_IF_HUNGRY(Msg)); 
01185         return Result;
01186     }
01187 
01188     return DialogOp::Message(Message);
01189 }  
01190 
01191 
01192 /******************************************************************************************
01193 >   INT32 BitmapExportPreviewDialog::GetPaletteIndexOfColour( ReDrawInfoType* param )
01194     Author:     Alex_Price (Xara Group Ltd) <camelotdev@xara.com>
01195     Created:    21/07/99
01196     Inputs:     param - Holds the mouse information needed
01197     Returns:    -1 if something went wrong, otherwise the relevant palette index.
01198     Purpose:    When the user clicks in, or moves the mouse over a pixel in one of the 
01199                 preview images, this function is called to work out the actual palette 
01200                 entry of the colour that the pixel uses.
01201 ******************************************************************************************/
01202 INT32 BitmapExportPreviewDialog::GetPaletteIndexOfColour( ReDrawInfoType* param, CGadgetID Gadget )
01203 {
01204     //  How big is a pixel in millipoints? - need this for conversion.
01205     INT32 pixelSize = 72000 / param->Dpi;
01206 
01207     //  Get the current mouse position.
01208     INT32 MouseX = param->pMousePos->x;
01209     INT32 MouseY = param->pMousePos->y;
01210 
01211     //  The values above are mouse positions in the preview window.
01212     //  To get the actual values in the bitmap view rectangle, we
01213     //  have to make an adjustment.
01214     //  ( Add 1 to avoid problems at the top and right-hand edges of the bitmap).
01215     MouseX -= m_BitmapView.lo.x + 1;
01216     MouseY -= m_BitmapView.lo.y + 1;
01217 
01218     //  We now have to scale these values from values in the bitmap
01219     //  view rectangle to values in the actual bitmap. The zoom
01220     //  factor and scaling factor contains the information we need for this.
01221     double ConversionFactor = 0.0;
01222     if( m_ActiveBitmap == 1 )
01223     {
01224         ConversionFactor = m_ZoomFactor;
01225     }
01226     else if( m_ActiveBitmap == 2 )
01227     {
01228         ConversionFactor = m_ZoomFactor * m_Scaling;
01229     }
01230     MouseX = ( INT32 )( MouseX * 100.0 / ConversionFactor );
01231     MouseY = ( INT32 )( MouseY * 100.0 / ConversionFactor );
01232 
01233     //  If the pointer is inside the bitmap preview control
01234     //  but outside the bitmap, ( can easily happen when
01235     //  'Zoom to fit' is clicked ), then we don't want
01236     //  to do anything else.
01237     if ( ( MouseX < 0) || ( MouseX >= m_Width) ||
01238          ( MouseY < 0) || ( MouseY >= m_Height) )
01239     {
01240         return -1;
01241     }
01242 
01243     //  Convert our mouse position into pixels.
01244     MouseX /= pixelSize;
01245     MouseY /= pixelSize;
01246 
01247     //  We now have the position of the pixel in the bitmap
01248     //  that the user has put the mouse over.
01249     //  We now need to get the palette index of the 
01250     //  corresponding colour.
01251 
01252     KernelBitmap * pBitmapToUse;
01253     if ( Gadget == _R(IDC_REDRAW1) )
01254         pBitmapToUse = BitmapData[0].m_pBitmap;
01255     else if ( Gadget == _R(IDC_REDRAW2) )
01256         pBitmapToUse = BitmapData[1].m_pBitmap;
01257     else
01258         pBitmapToUse = NULL;
01259 
01260     //  If there is no bitmap being previewed, then finish here.
01261     if( pBitmapToUse == NULL )
01262         return -1;
01263 
01264     NodeBitmap NB;
01265     NodeBitmap * pNodeBitmap = &NB;
01266 
01267     pNodeBitmap->GetBitmapRef()->SetBitmap( pBitmapToUse );
01268     ENSURE(pNodeBitmap->GetBitmap()->ActualBitmap != NULL, "No bitmap object found!");
01269 
01270     KernelBitmap* pBit = pNodeBitmap->GetBitmap();
01271     
01272     //  Need to alter the mouse position to take account of any change in bitmap size 
01273     //  or dpi which is not transmitted to this class.
01274     BitmapInfo BmapInfo;
01275     pBit->ActualBitmap->GetInfo( &BmapInfo );
01276     INT32 Width = BmapInfo.PixelWidth;
01277     INT32 Height    = BmapInfo.PixelHeight;
01278 
01279     INT32 NewWidth  = pBit->GetRecommendedWidth();
01280     INT32 NewHeight = pBit->GetRecommendedHeight();
01281     NewWidth        /= pixelSize;
01282     NewHeight       /= pixelSize;
01283 
01284     MouseX = MouseX * ( Width ) / NewWidth;
01285     MouseY = MouseY * ( Height ) / NewHeight;
01286 
01287     // we don't want to be subtracting one from the values above anymore
01288     // (to allow the indexed colour to correspond to the eye dropper location)
01289     // however, this leads us to a few problems - since it is now possible to
01290     // access invalid regions within the bitmap.  SOLUTION:  if were at the extents
01291     // of the bitmap, then allow us to subtract 1 (we can't do much else)
01292     if (MouseX >= Width)    { MouseX = Width-1; }
01293     if (MouseY >= Height)   { MouseY = Height-1; }
01294 
01295     //  Get the palette from the BmapPrevDlg class.
01296     //  Don't need to do this every time the mouse moves.
01297 //  ExtendedPalette* pPal = BmapPrevDlg::m_pExportOptions->GetExtendedPalette();
01298     INT32 PaletteIndex = pBit->ReturnPaletteIndexUsed( MouseX, MouseY );
01299 
01300     return PaletteIndex;
01301 }
01302 
01303 
01304 
01305 /********************************************************************************************
01306 
01307   > BOOL BitmapExportPreviewDialog::DoBrowserPreview(BrowserPreviewOptions BrowserOptions)
01308 
01309     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
01310     Created:    7/7/97
01311     Inputs:     BrowserOptions - options to be used when generating the html page
01312     Outputs:    -
01313     Returns:    TRUE if successful, FALSE otherwise
01314     Purpose:    Browser previewing. Simply calls GenerateHTMLStub function in the bitmap data 
01315                 object to do the work
01316 
01317 ********************************************************************************************/
01318 
01319 BOOL BitmapExportPreviewDialog::DoBrowserPreview(BrowserPreviewOptions BrowserOptions)
01320 {
01321     if ((m_ActiveBitmap == 1) || (m_ActiveBitmap == 2))
01322         return BitmapData[m_ActiveBitmap - 1].GenerateHTMLStub(BrowserOptions);
01323     else
01324         return FALSE;
01325 }
01326 
01327 
01328 
01329 /********************************************************************************************
01330 
01331 >   void BitmapExportPreviewDialog::OnZoomTool()
01332 
01333     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
01334     Created:    10/5/97
01335     Inputs:     -
01336     Outputs:    -
01337     Returns:    -
01338     Purpose:    Selects the zoom tool and displays the zoom tool button pressed (and the push 
01339                 tool one) released.
01340 
01341 ********************************************************************************************/
01342 
01343 void BitmapExportPreviewDialog::OnZoomTool()
01344 {
01345     //  When the Zoom is clicked, make sure that the Color Selector and Push
01346     //  tools are deselected.
01347     SetLongGadgetValue( _R(IDC_COLOUR_SELECTOR), FALSE );
01348     SetLongGadgetValue( _R(IDC_PUSH_TOOL), FALSE );
01349     //  Select the Push tool
01350     SetLongGadgetValue( _R(IDC_ZOOM_TOOL), TRUE );
01351 
01352     //  Set this as the current tool
01353     m_CurrentTool = PREVIEW_ZOOM_TOOL;
01354 }
01355 
01356 /******************************************************************************************
01357 
01358 >   void BitmapExportPreviewDialog::OnColourSelectorTool()
01359 
01360     Author:     Alex_Price (Xara Group Ltd) <camelotdev@xara.com>
01361 
01362     Created:    20/07/99
01363 
01364     Inputs:     -
01365 
01366     Returns:    -
01367 
01368     Purpose:    This function is called when the user clicks on the Colour Selector.
01369 
01370 ******************************************************************************************/
01371 
01372 
01373 void BitmapExportPreviewDialog::OnColourSelectorTool()
01374 {
01375     //  When the Colour Selector is clicked, make sure that the Zoom and Push
01376     //  tools are deselected.
01377     SetLongGadgetValue( _R(IDC_ZOOM_TOOL), FALSE );
01378     SetLongGadgetValue( _R(IDC_PUSH_TOOL), FALSE );
01379     //  Select the Colour Selector
01380     SetLongGadgetValue( _R(IDC_COLOUR_SELECTOR), TRUE );
01381 
01382     //  Set this as the current tool
01383     m_CurrentTool = PREVIEW_COLOUR_SELECTOR_TOOL;
01384 }
01385 
01386 /********************************************************************************************
01387 
01388 >   void BitmapExportPreviewDialog::OnPushTool()
01389 
01390     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
01391     Created:    10/5/97
01392     Inputs:     -
01393     Outputs:    -
01394     Returns:    -
01395     Purpose:    Selects the push tool and displays the push tool button pressed (and the zoom
01396                 tool one) released.
01397 
01398 ********************************************************************************************/
01399 
01400 void BitmapExportPreviewDialog::OnPushTool()
01401 {
01402     //  When the Push is clicked, make sure that the Color Selector and Zoom 
01403     //  tools are deselected.
01404     SetLongGadgetValue( _R(IDC_COLOUR_SELECTOR), FALSE );
01405     SetLongGadgetValue( _R(IDC_ZOOM_TOOL), FALSE );
01406     //  Select the Push tool
01407     SetLongGadgetValue( _R(IDC_PUSH_TOOL), TRUE );
01408 
01409     //  Set this as the current tool
01410     m_CurrentTool = PREVIEW_PUSH_TOOL;
01411 }
01412 
01413 
01414 /********************************************************************************************
01415 >   void BitmapExportPreviewDialog::On1to1()
01416     Author:     Jonathan_Payne (Xara Group Ltd) <camelotdev@xara.com> (from Stefan)
01417     Created:    14/12/2000
01418     Purpose:    Calculates and displays new view so one pixel in the final image is equal
01419                 to one pixel in the preview
01420 ********************************************************************************************/
01421 void BitmapExportPreviewDialog::On1to1()
01422 {
01423     // get the control size
01424     ReDrawInfoType param;
01425     GetKernelRenderedGadgetInfo(_R(IDC_REDRAW1), &param);
01426     MILLIPOINT w = param.dx;
01427     MILLIPOINT h = param.dy;
01428 
01429     ERROR3IF(!BitmapData[0].m_pBitmap, "No bitmap");
01430     ERROR3IF(BitmapData[0].m_pBitmap->GetHorizontalDPI() != BitmapData[0].m_pBitmap->GetVerticalDPI(),
01431                     "Different horizontal and vertiacl DPIs might cause problems");
01432 
01433     // calculate zoom factor so that the whole bitmap fits in 
01434     m_ZoomFactor = (BitmapData[0].m_pBitmap->GetHorizontalDPI() / double(param.Dpi)) * 100.0;
01435     if (m_ZoomFactor <= 0) 
01436         m_ZoomFactor = MIN_ZOOM;
01437 
01438     // scale the bitmap width and height
01439     MILLIPOINT Width  = (MILLIPOINT)((m_Width  * m_ZoomFactor) / 100);
01440     MILLIPOINT Height = (MILLIPOINT)((m_Height * m_ZoomFactor) / 100);
01441 
01442     m_BitmapView.lo.x = w/2 - Width / 2;
01443     m_BitmapView.hi.x = w/2 + Width / 2;
01444     m_BitmapView.lo.y = h/2 - Height / 2;
01445     m_BitmapView.hi.y = h/2 + Height / 2;
01446 
01447     // make sure one of the corners is aligned at a pixel
01448 
01449     // get the pixel size in millipoints
01450     MILLIPOINT PixSize = 0;
01451     DocUnitList* pDocUnitList = DocUnitList::GetCurrentDocUnitList();
01452     ERROR3IF(pDocUnitList == NULL, "BmpPrefsDlg::InitDialog() - no pDocUnitList!");
01453     if (pDocUnitList != NULL)
01454     {
01455         Unit* pPixelUnit = pDocUnitList->FindUnit(PIXELS);
01456         ERROR3IF(pPixelUnit == NULL, "BmpPrefsDlg::InitDialog() - no pixel units!");
01457         if (pPixelUnit != NULL)
01458             PixSize = (MILLIPOINT) pPixelUnit->GetMillipoints();
01459     }
01460 
01461     // shift the rectangle, so that the lower left corner is aligned at a pixel boundary
01462     if (PixSize != 0)
01463     {
01464         MILLIPOINT ShiftX = m_BitmapView.lo.x % PixSize;
01465         MILLIPOINT ShiftY = m_BitmapView.lo.y % PixSize;
01466 
01467         m_BitmapView.Translate(-ShiftX, -ShiftY);
01468     }
01469 
01470 
01471     // display the new zoom factor
01472     DisplayZoomFactor();
01473     
01474     // Render the controls
01475     InvalidateGadget(_R(IDC_REDRAW1));
01476     InvalidateGadget(_R(IDC_REDRAW2));
01477 }
01478 
01479 /********************************************************************************************
01480 >   void BitmapExportPreviewDialog::On100Percent()
01481     Author:     Jonathan_Payne (Xara Group Ltd) <camelotdev@xara.com>
01482     Created:    14/12/2000
01483     Purpose:    Calculates and displays new view, so that the selected bitmap is visible at 100%
01484 ********************************************************************************************/
01485 void BitmapExportPreviewDialog::On100Percent()
01486 {
01487     if (m_ActiveBitmap == 1)
01488         CalcViewRect(100, NULL);
01489     else if (m_ActiveBitmap == 2)
01490         CalcViewRect(100 / m_Scaling, NULL);
01491 }
01492 
01493 
01494 /******************************************************************************************
01495 
01496 >   BOOL BitmapExportPreviewDialog::InitDialog()
01497 
01498     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
01499     Created:    11/4/97
01500     Returns:    TRUE if successful, else FALSE
01501     Purpose:    Sets initial dialog values 
01502     Errors:     -
01503     SeeAlso:    -
01504 
01505 ******************************************************************************************/
01506 
01507 BOOL BitmapExportPreviewDialog::InitDialog()
01508 {
01509     // Set up the bitmaps for the play controls
01510     // Uses the title defined in the rc file so do not specify any bitmaps
01511     SetGadgetBitmaps(_R(IDC_ZOOM_TOOL), 0, 0);
01512     SetGadgetBitmaps(_R(IDC_PUSH_TOOL), 0, 0);
01513     SetGadgetBitmaps(_R(IDC_ZOOM_TO_FIT), 0, 0);
01514     SetGadgetBitmaps(_R(IDC_1TO1), 0, 0);
01515     SetGadgetBitmaps(_R(IDC_100PERCENT), 0, 0);
01516     SetGadgetBitmaps(_R(IDC_COLOUR_SELECTOR), 0, 0 );
01517 
01518     // default to push button
01519     SetLongGadgetValue(_R(IDC_PUSH_TOOL), TRUE);
01520 
01521     DisplayZoomFactor();
01522 
01523     //  Initialise the file type drop-list
01524     InitFileTypeList();
01525 
01526     return TRUE;
01527 }
01528 
01529 
01530 /******************************************************************************************
01531 
01532 >   void BitmapExportPreviewDialog::InitFileTypeList()
01533 
01534     Author:     Alex_Price (Xara Group Ltd) <camelotdev@xara.com>
01535 
01536     Created:    06/10/99
01537 
01538     Inputs:     -
01539 
01540     Returns:    -
01541 
01542     Purpose:    This function is called to initialise the file type drop lists which enables
01543                 the user to switch the preview image between different file types
01544                 Also initialises the file type variable in BmapPrevDlg
01545 
01546 ******************************************************************************************/
01547 void BitmapExportPreviewDialog::InitFileTypeList()
01548 {
01549     // Make sure the list is empty
01550     DeleteAllValues( _R(IDC_FILE_TYPE_LIST) );
01551 
01552 PORTNOTE("export", "Removed BMP")
01553     //  Add the necessary strings to the list. 
01554     //  This is the complete collection of them.
01555     
01556     enum
01557     {
01558         idComboPng      = 0,
01559         idComboJpg,
01560         idComboGif,
01561         idComboBmp
01562     };
01563 
01564     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST), _R(IDS_FILE_TYPE_PNG), FALSE, idComboPng );
01565     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST), _R(IDS_FILE_TYPE_JPG), FALSE, idComboJpg );
01566     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST), _R(IDS_FILE_TYPE_GIF), FALSE, idComboGif );
01567 #if !defined(EXCLUDE_FROM_XARALX)
01568     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST), _R(IDS_FILE_TYPE_BMP), FALSE, idComboBmp );
01569 #endif
01570 
01571     //  Repeat what is necessary for the second drop list.
01572     DeleteAllValues( _R(IDC_FILE_TYPE_LIST2) );
01573 
01574     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST2), _R(IDS_FILE_TYPE_PNG), FALSE, idComboPng );
01575     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST2), _R(IDS_FILE_TYPE_JPG), FALSE, idComboJpg );
01576     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST2), _R(IDS_FILE_TYPE_GIF), FALSE, idComboGif );
01577 #if !defined(EXCLUDE_FROM_XARALX)
01578     SetStringGadgetValue( _R(IDC_FILE_TYPE_LIST2), _R(IDS_FILE_TYPE_BMP), FALSE, idComboBmp );
01579 #endif
01580 
01581     UINT32              idString = BmapPrevDlg::m_pExportOptions->GetFilterNameStrID();
01582     if( idString == _R(IDN_FILTERNAME_GIF) ) // its a windows bitmap bmp type
01583     {
01584         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST), idComboGif );
01585         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST2), idComboGif );
01586     }
01587     else
01588     if( idString == _R(IDT_FILTERNAME_BMP) ) // its a windows bitmap bmp type
01589     {
01590         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST), idComboBmp );
01591         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST2), idComboBmp );
01592     }
01593     else
01594     if( idString == _R(IDS_JPG_EXP_FILTERNAME) ) // its a jpeg type
01595     {
01596         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST), idComboJpg );
01597         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST2), idComboJpg );
01598     }
01599     else
01600     {
01601 //  case _R(IDS_FILTERNAME_PNG): // its a png
01602         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST), idComboPng );
01603         SetSelectedValueIndex( _R(IDC_FILE_TYPE_LIST2), idComboPng );
01604 
01605         // Preview doesn't work for IM filters, so hide combos
01606         if( idString != _R(IDS_FILTERNAME_PNG) )
01607         {
01608             HideGadget( _R(IDC_FILE_TYPE_LIST), TRUE );
01609             HideGadget( _R(IDC_FILE_TYPE_LIST2), TRUE );
01610         }
01611     }
01612     
01613     //  Set the lists to the correct length
01614     SetComboListLength( _R(IDC_FILE_TYPE_LIST) );
01615     SetComboListLength( _R(IDC_FILE_TYPE_LIST2) );
01616 
01617     EnableGadget( _R(IDC_FILE_TYPE_LIST),   !BmapPrevDlg::m_bIsCreateBitmap );
01618     EnableGadget( _R(IDC_FILE_TYPE_LIST2),  !BmapPrevDlg::m_bIsCreateBitmap );
01619 }
01620 
01621 
01622 /******************************************************************************************
01623 
01624 >   void BitmapExportPreviewDialog::HandleFileTypeListChange( INT32 Index )
01625 
01626     Author:     Alex_Price (Xara Group Ltd) <camelotdev@xara.com>
01627 
01628     Created:    06/10/99
01629 
01630     Inputs:     An index telling us which of the 2 drop-lists being referred to.
01631                 Equal to 0 for the first list, and 1 for the second.
01632 
01633     Returns:    -
01634 
01635     Purpose:    When the user makes a selection from the file type drop-lists, this function
01636                 carries out any necessary changes required.
01637 
01638 ******************************************************************************************/
01639 
01640 void BitmapExportPreviewDialog::HandleFileTypeListChange( INT32 Index )
01641 {
01642     //  Get the user's selection
01643     String_16 FileTypeSelected;
01644     if( Index == 0 )
01645         FileTypeSelected = GetStringGadgetValue( _R(IDC_FILE_TYPE_LIST) );
01646     else if( Index == 1 )
01647         FileTypeSelected = GetStringGadgetValue( _R(IDC_FILE_TYPE_LIST2) );
01648 
01649     BitmapExportOptions * pNewOptions = NULL;
01650 
01651     //  Did the user select 'Gif'?
01652     if( FileTypeSelected.IsIdentical( String_16( _R(IDS_FILE_TYPE_GIF) ) ) )
01653     {
01654         //  Was 'Gif' previously selected?
01655         //  If so, there is nothing to do, so return now.
01656         if (BmapPrevDlg::m_pExportOptions->GetFilterNameStrID() == _R(IDN_FILTERNAME_GIF))
01657             return;
01658         pNewOptions = new GIFExportOptions();
01659     }
01660     //  Did the user select 'Png'?
01661     else if( FileTypeSelected.IsIdentical( String_16( _R(IDS_FILE_TYPE_PNG) ) ) )
01662     {
01663         //  Was 'Png' previously selected?
01664         //  If so, there is nothing to do, so return now.
01665         if (BmapPrevDlg::m_pExportOptions->GetFilterNameStrID() == _R(IDS_FILTERNAME_PNG))
01666             return;
01667         pNewOptions = new PNGExportOptions();
01668     }
01669     //  Did the user select 'Bmp'?
01670     else if( FileTypeSelected.IsIdentical( String_16( _R(IDS_FILE_TYPE_BMP) ) ) )
01671     {
01672         //  Was 'Bmp' previously selected?
01673         //  If so, there is nothing to do, so return now.
01674         if (BmapPrevDlg::m_pExportOptions->GetFilterNameStrID() == _R(IDT_FILTERNAME_BMP))
01675             return;
01676         pNewOptions = new BMPExportOptions();
01677     }
01678     //  Did the user select 'Jpg'?
01679     else if( FileTypeSelected.IsIdentical( String_16( _R(IDS_FILE_TYPE_JPG) ) ) )
01680     {
01681         //  Was 'Jpg' previously selected?
01682         //  If so, there is nothing to do, so return now.
01683         if (BmapPrevDlg::m_pExportOptions->GetFilterNameStrID() == _R(IDS_JPG_EXP_FILTERNAME))
01684             return;
01685         pNewOptions = new JPEGExportOptions();
01686     }
01687     
01688     // failled to create some new options
01689     if (!pNewOptions)
01690         return;
01691 
01692     // copy as much as we can from the old options
01693     pNewOptions->RetrieveDefaults();
01694     pNewOptions->CopyFrom(BitmapData[Index].m_pOptions);
01695 
01696     // Bodge fix so BMPs don't gain background transparency as they do not support it
01697     if (FileTypeSelected.IsIdentical(String_16(_R(IDS_FILE_TYPE_BMP))))
01698         pNewOptions->SetBackgroundTransparency(FALSE);
01699 
01700     // juggle the export objects so we dont hold on to too many
01701     // It appears that BmapPrevDlg::m_pExportOptions is either
01702     // NULL
01703     // Or holds a pointer to the [0] options but doesn't own it
01704     // Or holds a pointer to the [1] options but doesn't own it
01705     // Or holds a poitner to an objects object that it does own
01706     // ...
01707     if (BmapPrevDlg::m_pExportOptions != NULL &&
01708         BmapPrevDlg::m_pExportOptions != BitmapData[0].m_pOptions &&
01709         BmapPrevDlg::m_pExportOptions != BitmapData[1].m_pOptions
01710         )
01711     {
01712         // The static options object is not either of the preview objects, so delete it
01713         delete BmapPrevDlg::m_pExportOptions;
01714         BmapPrevDlg::m_pExportOptions = NULL;
01715     }
01716     BmapPrevDlg::m_pExportOptions = NULL;
01717 
01718     // Delete the old options (if no-one else owns them)
01719     if (BitmapData[0].m_pOptions != BitmapData[1].m_pOptions)
01720     {
01721         delete BitmapData[Index].m_pOptions;
01722         BitmapData[Index].m_pOptions = NULL;
01723     }
01724 
01725     // set the new current export options
01726     BitmapData[Index].m_pOptions = pNewOptions;
01727     BmapPrevDlg::m_pExportOptions = pNewOptions;
01728 
01729     // set the filter to match the new options
01730     m_pBmpFilter = pNewOptions->FindBitmapFilterForTheseExportOptions();
01731 
01732     // set this as the active bitmap
01733     ChangeActiveBitmap(Index+1);
01734 
01735     // tell the tab part of the dlg to update the tabs and the preview
01736     if (m_pParentDlg)
01737     {
01738         //BROADCAST_TO_CLASS( DialogMsg(m_pParentDlg->WindowID, DIM_SOFT_COMMIT, 0, NULL, 0), DialogOp );
01739         CDlgResID page = m_pParentDlg->GetCurrentPageID();
01740         m_pParentDlg->DoPreview();
01741         m_pParentDlg->TalkToPage(page);
01742         m_pParentDlg->UpdateCurrentTab();
01743     }
01744 }
01745 
01746 
01747 /********************************************************************************************
01748 
01749 >   void BitmapExportPreviewDialog::RenderControl(ReDrawInfoType* pExtraInfo, UINT32 GadgetID)
01750 
01751     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
01752     Created:    11/4/97
01753     Inputs:     pExtraInfo - The structure that has the extra data we need to start rendering
01754                 GadgetID - specifies one of the two draw controls
01755     Purpose:    The redraw handling for the two draw controls in the dialog. Depending on the 
01756                 zoom flag (m_ZoomRectRender) either the zoom rectangle, or the whole
01757                 bitmap is drawn in the control.
01758 
01759 ********************************************************************************************/
01760 
01761 void BitmapExportPreviewDialog::RenderControl(ReDrawInfoType* pExtraInfo, UINT32 GadgetID)
01762 {
01763     //  Ok, this may not be the best place to do this, but it will do for the moment.
01764     //  If we are doing a 'Create Bitmap Copy...', then make sure that the file type 
01765     //  drop-lists are disabled.
01766 //J if( !( m_pParentDlg->WantToShowFileTypeDropLists() ) )
01767 //J {
01768 //J     EnableGadget( _R(IDC_FILE_TYPE_LIST),   FALSE );
01769 //J     EnableGadget( _R(IDC_FILE_TYPE_LIST2),  FALSE );
01770 //J }
01771 
01772     if (pExtraInfo == NULL)
01773         return;
01774 
01775     // Go get a render region
01776     DocRect VirtualSize(0, 0, pExtraInfo->dx, pExtraInfo->dy);
01777 
01778     // normall redraw operation - draw our bitmap
01779     
01780     // If we haven't already created our render region then go and create it
01781     BOOL StartedOk = TRUE;
01782     if (m_pRender == NULL)
01783     {
01784         // This will call start render for us
01785         m_pRender = (GRenderRegion *)CreateGRenderRegion(&VirtualSize, pExtraInfo);
01786     }
01787     else
01788     {
01789         // and delete the render region and its (dialog) view
01790         View * pDialogView = m_pRender->GetRenderView();
01791         
01792         if (pDialogView)
01793         {
01794             // Try and create the bitmap etc
01795             StartedOk = m_pRender->AttachDevice( pDialogView, pExtraInfo->pDC->GetDC(), NULL );
01796 
01797             // Try and start the render region
01798             StartedOk = StartedOk && m_pRender->StartRender();
01799         }
01800         else
01801             StartedOk = FALSE;
01802     }
01803 
01804     // if we have a render region then go and use it
01805     if (m_pRender != NULL && StartedOk)
01806     {
01807         // Code stolen from ColourEditDlg::RenderControl
01808         DialogColourInfo RedrawColours;             // Get a supplier for default dlg colours
01809         INT32 PixelSize = 72000 / pExtraInfo->Dpi;  // Size of output pixel in millipoints
01810 
01811         // Render the attributes and then a rectangle
01812         m_pRender->SaveContext();
01813 
01814         // Get the current bitmap for the passed control
01815         KernelBitmap * pBitmapToUse;
01816         //  The ( 1-based ) number of the bitmap currently being rendered.
01817         if (GadgetID == _R(IDC_REDRAW1))
01818         {
01819             pBitmapToUse = BitmapData[0].m_pBitmap;
01820         }
01821         else if (GadgetID == _R(IDC_REDRAW2))
01822         {
01823             pBitmapToUse = BitmapData[1].m_pBitmap;
01824         }
01825         else
01826             pBitmapToUse = NULL;
01827         
01828         // Draw a backgound making sure we blat anything previously there with the dialog
01829         // background colour
01830         m_pRender->SetFillColour(RedrawColours.DialogBack());
01831         if (pBitmapToUse)
01832             m_pRender->SetLineColour(COLOUR_TRANS); 
01833         else
01834             m_pRender->SetLineColour(COLOUR_BLACK); 
01835         m_pRender->DrawRect(&VirtualSize);
01836 
01837         if (pBitmapToUse)
01838         {
01839             // set the dither origin, so its hooked to the top left corner of the bitmap
01840             // needs to be converted in pixels
01841             m_pRender->GetDrawContext()->SetHalftoneOrigin( m_BitmapView.lo.x / PixelSize, 
01842                             - m_BitmapView.lo.y / PixelSize); // needs to negate the value in y 
01843 
01844             // Code stolen from BfxDlg::RenderBitmap
01845             m_pRender->SetLineColour(COLOUR_TRANS);
01846 
01847             NodeBitmap NB;
01848             NodeBitmap * pNodeBitmap = &NB;
01849         
01850 //          if (!((pNodeBitmap == NULL) || (!pNodeBitmap->SetUpPath(12,12))))
01851             if ((pNodeBitmap != NULL) && pNodeBitmap->SetUpPath(12,12))
01852             {
01853                 // Get a new bitmap object for this node.
01854                 pNodeBitmap->GetBitmapRef()->SetBitmap(pBitmapToUse);
01855                 ENSURE(pNodeBitmap->GetBitmap()->ActualBitmap != NULL, "No bitmap object found!");
01856         
01857                 // And set this in our bitmap node
01858                 pNodeBitmap->CreateShape(m_BitmapView);
01859 
01860                 //  Only do the render if we are not doing a double render which is required
01861                 //  for maintaining the number of colours in the palette in certain circumstances
01862 //              if( !( m_pParentDlg->m_bDoNotRenderThisTime | m_pParentDlg->m_bDoNotRenderThisTime2 ) )
01863                     pNodeBitmap->Render(m_pRender);
01864             }
01865         }
01866         else
01867         {
01868             // Draw the no bitmap present cross i.e. vertical
01869             // And Deflate the rect by 1 pixels so we draw to the outer lines
01870             VirtualSize.Inflate(-PixelSize);
01871             INT32 Width = VirtualSize.Width();
01872             INT32 Height = VirtualSize.Height();
01873             m_pRender->SetLineWidth(0);
01874             m_pRender->SetLineColour(COLOUR_BLACK); //RedrawColours.ButtonShadow());
01875             m_pRender->DrawLine(DocCoord(VirtualSize.lo.x + Width/2, VirtualSize.lo.y),
01876                                 DocCoord(VirtualSize.lo.x + Width/2, VirtualSize.hi.y));
01877             m_pRender->DrawLine(DocCoord(VirtualSize.lo.x, VirtualSize.lo.y + Height/2),
01878                                 DocCoord(VirtualSize.hi.x, VirtualSize.lo.y + Height/2));
01879 
01880             // Now display can't preview text
01881             String_128      str( _T("Preview is not supported for this image format") );
01882             DocRect         rect;
01883             m_pRender->GetFixedSystemTextSize( &str, &rect );
01884             rect.Translate( VirtualSize.lo.x + ( Width / 2 ) - ( rect.Width() / 2 ),
01885                             VirtualSize.lo.y + ( Height / 2 ) - ( rect.Height() / 2 ) );
01886             m_pRender->DrawFixedSystemText( &str, rect );
01887         }
01888 
01889         m_pRender->RestoreContext();
01890 
01891         // Blit to the screen
01892         m_pRender->StopRender();
01893 
01894         // Get rid of the render region, now done in the destructor
01895         DestroyGRenderRegion(m_pRender);
01896         m_pRender = NULL;
01897 
01898         //  May have to redraw cursor.
01899         m_bWantCursorRedrawn = TRUE;
01900     }
01901 
01902     // test for zoom rectangle request
01903     if ((m_ZoomRectRender) && (m_StartPos != m_CurrentPos)) 
01904     {
01905         // draw inverted rectangle only
01906         
01907         // create OSRenderRegion, because GRenderRegion doesn't handle EOR-ed draw
01908         RenderRegion *pRender = CreateOSRenderRegion(&VirtualSize, pExtraInfo);
01909 
01910         if (pRender == NULL)
01911             return;
01912 
01913         // Render the attributes and then a rectangle
01914         pRender->SaveContext();
01915 
01916         pRender->SetDrawingMode(DM_EORPEN);
01917         
01918         pRender->SetFillColour(COLOUR_TRANS);
01919         pRender->SetLineColour(COLOUR_XORSELECT); 
01920 
01921         // draw the rect
01922         DocRect rc;
01923         rc.lo.x = m_StartPos.x < m_CurrentPos.x ? m_StartPos.x : m_CurrentPos.x;
01924         rc.lo.y = m_StartPos.y < m_CurrentPos.y ? m_StartPos.y : m_CurrentPos.y;
01925         rc.hi.x = m_StartPos.x > m_CurrentPos.x ? m_StartPos.x : m_CurrentPos.x;
01926         rc.hi.y = m_StartPos.y > m_CurrentPos.y ? m_StartPos.y : m_CurrentPos.y;
01927 
01928         pRender->DrawRect(&rc);
01929 
01930         pRender->RestoreContext();
01931 
01932         // destroy the render region
01933         DestroyOSRenderRegion(pRender);
01934     } 
01935 }
01936 
01937 
01938 /*******************************************************************************************
01939 
01940 >   OpState BitmapExportPreviewDialog::GetState(String_256*, OpDescriptor*)
01941 
01942     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
01943     Created:    11/4/97
01944     Purpose:    Returns the OpState of the Preview dialogue operation
01945 
01946 *******************************************************************************************/
01947 
01948 OpState BitmapExportPreviewDialog::GetState(String_256*, OpDescriptor*)
01949 {
01950     return OpState(FALSE, FALSE);
01951 }
01952 
01953          
01954 
01955 /*******************************************************************************************
01956 
01957 >   BOOL BitmapExportPreviewDialog::Init()
01958 
01959     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
01960     Created:    11/4/97
01961     Returns:    FALSE if it fails (due to lack of memory)
01962     Purpose:    Creates an OpDescriptor for a Preview Dialog
01963 
01964 *******************************************************************************************/
01965 
01966 BOOL BitmapExportPreviewDialog::Init()
01967 {  
01968     return RegisterOpDescriptor(0,                              // Tool ID
01969                                 _R(IDS_BITMAPPREVIEWDIALOG),                // String resource ID
01970                                 CC_RUNTIME_CLASS(BitmapExportPreviewDialog),// Runtime class
01971                                 OPTOKEN_BITMAPPREVIEWDIALOG,            // Token string
01972                                 BitmapExportPreviewDialog::GetState,        // GetState function
01973                                 0,                              // Help ID
01974                                 0,                              // Bubble ID
01975                                 0,                              // Resource ID
01976                                 0,                              // Control ID
01977                                 SYSTEMBAR_ILLEGAL,              // Bar ID
01978                                 FALSE,                          // Recieve system messages
01979                                 FALSE,                          // Smart duplicate operation
01980                                 TRUE,                           // Clean operation
01981                                 0,                              // No vertical counterpart
01982                                 0);                             // String for one copy only
01983 }   
01984          
01985 
01986 /*******************************************************************************************
01987 
01988 >   void BitmapExportPreviewDialog::InitPreviewDialog(BmapPrevDlg *pParentDlg, Filter *pFilter)
01989 
01990     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys)
01991     Created:    11/4/97
01992     Inputs:     pFilter - pointer to the export filter to be used for creating temp files
01993     Purpose:    Creates and shows a Preview dialog
01994 
01995 *******************************************************************************************/
01996 
01997 void BitmapExportPreviewDialog::InitPreviewDialog(BmapPrevDlg *pParentDlg, Filter *pFilter)
01998 {
01999     ERROR3IF(pFilter == NULL, "BitmapExportPreviewDialog::InitPreviewDialog - no filter");
02000     ERROR3IF(pParentDlg == NULL, "BitmapExportPreviewDialog::InitPreviewDialog - no filter");
02001 
02002     // remember the pointer to the parent
02003     m_pParentDlg = pParentDlg;
02004 
02005     // remember the filter
02006     m_pBmpFilter = (BaseBitmapFilter*)pFilter;
02007 
02008     if (pFilter == NULL)
02009     {
02010         InformError(_R(IDT_CANT_FIND_FILTER));
02011         FailAndExecute(); 
02012 
02013         // Finished the operation
02014         End();
02015         return;
02016     }
02017 
02018     // give this object to the menu operation
02019     OpPreviewPopupCommand::m_pDialog = this;
02020 
02021     // close the progress bar indicator
02022     SmashSlowJob();
02023 
02024     // Force the dialog box to be created.
02025     // If it is non-modal it must be opened if the create works ok.
02026     // If it is modal then don't call the open
02027     if (Create())
02028     {
02029         // If dialog is not Modal do this now
02030         // Otherwise set up happens in the message handler
02031         if (Mode == MODELESS)
02032         {
02033             // Set the initial control values 
02034             InitDialog();
02035 
02036             // If modeless then call open Open()
02037             Open();
02038         }
02039     }
02040     else
02041     {
02042         TRACE( _T("Failed to create Render Preview Dialog\n"));
02043         // Could not create the dialog box so call inform error 
02044         InformError();                      // Show user the error
02045         End();                              // End the operation 
02046     }
02047 }
02048 
02049 
02050 
02051 
02052 /***********************************************************************************************
02053 
02054 >   void BitmapExportPreviewDialog::CalcViewRect(double NewZoomFactor, DocCoord *pos)
02055 
02056     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02057     Created:    20/04/97
02058     Inputs:     NewZoomFactor - the new zoom factor
02059                 Pos - the click position, indicating the centre of the new view
02060     Purpose:    Calculates a new view rectangle using the zoom factor and the position. Pass 
02061                 a negative value for 'Zoom to Fit'. If null is passed for pos, the centre of 
02062                 the control is assumed.
02063     Returns:    None.
02064                                                                  
02065 ***********************************************************************************************/
02066 
02067 void BitmapExportPreviewDialog::CalcViewRect(double NewZoomFactor, DocCoord *pos)
02068 {
02069     // get the control size
02070     ReDrawInfoType param;
02071     GetKernelRenderedGadgetInfo(_R(IDC_REDRAW1), &param);
02072     MILLIPOINT w = param.dx;
02073     MILLIPOINT h = param.dy;
02074 
02075     if (NewZoomFactor < 0)      // zoom to fit
02076     {
02077         // calculate zoom factor so that the whole bitmap fits in 
02078         m_ZoomFactor = (double(w)/m_Width < double(h)/m_Height ? 
02079                 (double(w)/m_Width) * 100 : (double(h)/m_Height) * 100);
02080         if (m_ZoomFactor <= 0)
02081             m_ZoomFactor = MIN_ZOOM;
02082 
02083         // scale the bitmap width and height
02084         MILLIPOINT Width  = (MILLIPOINT)((m_Width  * m_ZoomFactor) / 100);
02085         MILLIPOINT Height = (MILLIPOINT)((m_Height * m_ZoomFactor) / 100);
02086 
02087         m_BitmapView.lo.x = w/2 - Width / 2;
02088         m_BitmapView.hi.x = w/2 + Width / 2;
02089         m_BitmapView.lo.y = h/2 - Height / 2;
02090         m_BitmapView.hi.y = h/2 + Height / 2;
02091     }
02092     else 
02093     {
02094         double OldZoomFactor = m_ZoomFactor;
02095 
02096         // set the new zoom factor
02097         m_ZoomFactor = NewZoomFactor;
02098 
02099         // check for zoom factor > MAX_ZOOM
02100         
02101         // check for the first bitmap
02102         if (NewZoomFactor > (double)MAX_ZOOM) 
02103             m_ZoomFactor = (double) MAX_ZOOM;
02104 
02105         // now for the second one
02106         if (m_ZoomFactor * m_Scaling > (double)MAX_ZOOM)
02107             m_ZoomFactor = double(MAX_ZOOM) / m_Scaling;
02108             
02109 
02110         // check for zoom factor < MIN_ZOOM
02111 
02112         // first bitmap
02113         if (m_ZoomFactor < (double)MIN_ZOOM) 
02114             m_ZoomFactor = (double) MIN_ZOOM;
02115 
02116         // the second one
02117         if (m_ZoomFactor * m_Scaling < (double)MIN_ZOOM)
02118             m_ZoomFactor = double(MIN_ZOOM) / m_Scaling;
02119         
02120 
02121         // scale the bitmap width and height
02122         MILLIPOINT Width  = (MILLIPOINT)((m_Width  * m_ZoomFactor) / 100);
02123         MILLIPOINT Height = (MILLIPOINT)((m_Height * m_ZoomFactor) / 100);
02124 
02125         // calculate new view based on the last one
02126 
02127         // find the centre of the view
02128         DocCoord Centre;
02129         Centre.x = (m_BitmapView.hi.x + m_BitmapView.lo.x) / 2;
02130         Centre.y = (m_BitmapView.hi.y + m_BitmapView.lo.y) / 2;
02131 
02132         // scale view
02133         m_BitmapView.lo.x = Centre.x - Width / 2;
02134         m_BitmapView.hi.x = Centre.x + Width / 2;
02135         m_BitmapView.lo.y = Centre.y - Height/ 2;
02136         m_BitmapView.hi.y = Centre.y + Height/ 2;
02137 
02138         
02139         DocCoord Pos;
02140         // if no position passed assume click in the middle of the control
02141         if (pos == NULL)
02142         {
02143             Pos.x = w/2;
02144             Pos.y = h/2; 
02145         }
02146         else 
02147             Pos = *pos;
02148 
02149         // scale the passed point according to the new zoom
02150         DocCoord ScaledPos;
02151         
02152         // test to prevent 'divide by zero' exception
02153         if (OldZoomFactor == 0)
02154             OldZoomFactor = MIN_ZOOM;
02155 
02156         ScaledPos.x = (MILLIPOINT)(Centre.x + (Pos.x - Centre.x) * (m_ZoomFactor / OldZoomFactor));
02157         ScaledPos.y = (MILLIPOINT)(Centre.y + (Pos.y - Centre.y) * (m_ZoomFactor / OldZoomFactor));
02158 
02159         // translate the new view rectangle to be centered on the scaled position
02160         m_BitmapView.Translate(w/2 - ScaledPos.x, h/2 - ScaledPos.y);
02161     }
02162 
02163     // make sure one of the corners is aligned at a pixel
02164 
02165     // get the pixel size in millipoints
02166     MILLIPOINT PixSize = 0;
02167     DocUnitList* pDocUnitList = DocUnitList::GetCurrentDocUnitList();
02168     ERROR3IF(pDocUnitList == NULL, "BmpPrefsDlg::InitDialog() - no pDocUnitList!");
02169     if (pDocUnitList != NULL)
02170     {
02171         Unit* pPixelUnit = pDocUnitList->FindUnit(PIXELS);
02172         ERROR3IF(pPixelUnit == NULL, "BmpPrefsDlg::InitDialog() - no pixel units!");
02173         if (pPixelUnit != NULL)
02174             PixSize = (MILLIPOINT) pPixelUnit->GetMillipoints();
02175     }
02176 
02177     // shift the rectangle, so that the lower left corner is aligned at a pixel boundary
02178     if (PixSize != 0)
02179     {
02180         MILLIPOINT ShiftX = m_BitmapView.lo.x % PixSize;
02181         MILLIPOINT ShiftY = m_BitmapView.lo.y % PixSize;
02182 
02183         m_BitmapView.Translate(-ShiftX, -ShiftY);
02184     }
02185 
02186 
02187     // display the new zoom factor
02188     DisplayZoomFactor();
02189     
02190     // Render the controls
02191     InvalidateGadget(_R(IDC_REDRAW1));
02192     InvalidateGadget(_R(IDC_REDRAW2));
02193 }
02194 
02195 
02196 
02197 /***********************************************************************************************
02198 
02199 >   void BitmapExportPreviewDialog::DoPush(DocCoord *NewPos)
02200 
02201     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02202     Created:    20/04/97
02203     Inputs:     NewPos - the new mouse position (in millipoints)
02204     Purpose:    Pushes the bitmaps by translating the current view rectangle.
02205     Returns:    None.
02206                                                                  
02207 ***********************************************************************************************/
02208 
02209 void BitmapExportPreviewDialog::DoPush(DocCoord *NewPos)
02210 {
02211     // translate the view 
02212     DocCoord diff(NewPos->x - m_CurrentPos.x, NewPos->y - m_CurrentPos.y);
02213     m_BitmapView.Translate(diff.x, diff.y);
02214 
02215     // remember the new position
02216     m_CurrentPos = *NewPos;
02217 
02218     // Render the controls
02219     InvalidateGadget(_R(IDC_REDRAW1));
02220     InvalidateGadget(_R(IDC_REDRAW2));
02221     PaintGadgetNow(_R(IDC_REDRAW1));
02222     PaintGadgetNow(_R(IDC_REDRAW2));
02223 }
02224 
02225 
02226 
02227 /***********************************************************************************************
02228 
02229 >   void BitmapExportPreviewDialog::DoZoom(DocCoord *NewPos)
02230 
02231     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02232     Created:    20/04/97
02233     Inputs:     NewPos - the new mouse position (in millipoints)
02234     Purpose:    Removes the last zoom rectangle and draws the new one as part of the zoom to 
02235                 rectangle operation
02236     Returns:    None.
02237                                                                  
02238 ***********************************************************************************************/
02239 
02240 void BitmapExportPreviewDialog::DoZoom(DocCoord *NewPos)
02241 {
02242     // remove the last rectangle
02243     DrawZoomRect();
02244 
02245     // remember and set the new rectangle coordinate
02246     m_CurrentPos = *NewPos;
02247 
02248     // draw a new rectangle
02249     DrawZoomRect();
02250 }
02251 
02252 
02253 
02254 /***********************************************************************************************
02255 
02256 >   void BitmapExportPreviewDialog::DrawZoomRect()
02257 
02258     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02259     Created:    20/04/97
02260     Inputs:     None.
02261     Purpose:    Draws the zoom rectangle, by setting the zoom flag and invalidating the controls.
02262     Returns:    None.
02263                                                                  
02264 ***********************************************************************************************/
02265 
02266 void BitmapExportPreviewDialog::DrawZoomRect()
02267 {
02268     // ask the redraw funcion to draw the zoom rectangle
02269     m_ZoomRectRender = TRUE;
02270     InvalidateGadget(_R(IDC_REDRAW1));
02271     InvalidateGadget(_R(IDC_REDRAW2));
02272     PaintGadgetNow(_R(IDC_REDRAW1));
02273     PaintGadgetNow(_R(IDC_REDRAW2));
02274     m_ZoomRectRender = FALSE;
02275 }
02276 
02277 
02278 
02279 /***********************************************************************************************
02280 
02281 >   void BitmapExportPreviewDialog::ZoomToRect()
02282 
02283     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02284     Created:    20/04/97
02285     Inputs:     None.
02286     Purpose:    Implements zoom to rectangle. The rectangle is defined by m_CurrentPos and 
02287                 m_StartPos. Very small rectangles are treated as click-zooms
02288     Returns:    None.
02289                                                                  
02290 ***********************************************************************************************/
02291 
02292 void BitmapExportPreviewDialog::ZoomToRect()
02293 {
02294     // find the centre of the view
02295     DocCoord Centre;
02296     Centre.x = (m_CurrentPos.x + m_StartPos.x) / 2;
02297     Centre.y = (m_CurrentPos.y + m_StartPos.y) / 2;
02298 
02299     DocCoord size;
02300     size.x = abs(m_CurrentPos.x - m_StartPos.x);
02301     size.y = abs(m_CurrentPos.y - m_StartPos.y);
02302 
02303     // check for very small rectangle
02304     if ((size.x < 3000) && (size.y < 3000) )
02305     {
02306         // treat this as a click zoom
02307         CalcViewRect(FindNearestZoom(!KeyPress::IsAdjustPressed()),&Centre);
02308     }
02309     else
02310     {
02311         // get the control size
02312         ReDrawInfoType param;
02313         GetKernelRenderedGadgetInfo(_R(IDC_REDRAW1), &param);
02314         MILLIPOINT w = param.dx;
02315         MILLIPOINT h = param.dy;
02316 
02317         // calc scaling factor
02318         double Scale = max(double(size.x) / w, double(size.y) / h);
02319 
02320         // check for zero scale
02321         if (fabs(Scale) < 0.0001)
02322             return;
02323 
02324         // calculate the new zoom factor
02325         double NewZoomFactor = m_ZoomFactor / Scale;
02326 
02327         // calculate the new view
02328         CalcViewRect(NewZoomFactor, &Centre);
02329     }
02330 }
02331 
02332 
02333 
02334 
02335 /***********************************************************************************************
02336 
02337 >   void BitmapExportPreviewDialog::ChangeActiveBitmap(UINT32 Active)
02338 
02339     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02340     Created:    20/04/97
02341     Inputs:     Active - the active bitmap - either 1 or 2
02342     Purpose:    Sets new active bitmap and makes the frame around it visible (and the one around 
02343                 the other bitmap invisible). The current zoom factor is also updated.
02344     Returns:    None.
02345                                                                  
02346 ***********************************************************************************************/
02347 
02348 void BitmapExportPreviewDialog::ChangeActiveBitmap(UINT32 Active)
02349 {
02350     ERROR3IF((Active != 1) && (Active != 2),"Invalid active bitmap passed");
02351 
02352     if (m_ActiveBitmap == Active) // no change
02353         return; 
02354 
02355     if (BitmapData[Active - 1].m_pBitmap == NULL)
02356         return; // can't select non-existent bitmap
02357 
02358     // remember it
02359     m_ActiveBitmap = Active;
02360 
02361     // THE export options are the active side of the export dlg
02362     if (BitmapData[m_ActiveBitmap - 1].m_pOptions)
02363     {
02364         // In other places the static pointer is handled carefully - but not here!
02365         BmapPrevDlg::m_pExportOptions = BitmapData[m_ActiveBitmap - 1].m_pOptions;
02366         // the filter should match THE export options
02367         m_pBmpFilter = BmapPrevDlg::m_pExportOptions->FindBitmapFilterForTheseExportOptions();
02368         if (m_pBmpFilter)
02369             m_pBmpFilter->SetExportOptions(BmapPrevDlg::m_pExportOptions);
02370     }
02371     
02372     // define the active one
02373     BOOL ActiveFirst = (Active == 1);
02374 
02375     // The palette sort data is out of date so force it to be regenerated the next time it is used
02376     BitmapExportPaletteInterface::InvalidateSortedPalette();
02377 
02378     // update the tab to reflect the new active side of the dlg
02379     if (m_pParentDlg)
02380         m_pParentDlg->UpdateCurrentTab();
02381 
02382     // update the frame title string
02383     DisplayZoomFactor();
02384 
02385     // hide the frame around the previous active control and show it around the new active one
02386 //  HideGadget(_R(IDC_ACTIVEFRAME1), !ActiveFirst);
02387 //  HideGadget(_R(IDC_ACTIVEFRAME2), ActiveFirst);
02388 
02389     EnableGadget(_R(IDC_ACTIVE1), ActiveFirst);
02390     EnableGadget(_R(IDC_ACTIVE2), !ActiveFirst);
02391     
02392     //  Since the active preview image has changed, have to enable/disable the appropriate
02393     //  file type drop-lists.
02394     //  If we want to have both of the drop-lists disabled, then we can return now.
02395     // cant change the frame if we are a create bitmap option
02396     if (!BmapPrevDlg::m_bIsCreateBitmap)
02397     {
02398         if( Active == 1 )
02399         {
02400             //  If the user has clicked on the first image, need to enable the first list, and
02401             //  disable the second list.
02402             EnableGadget( _R(IDC_FILE_TYPE_LIST),   TRUE );
02403             EnableGadget( _R(IDC_FILE_TYPE_LIST2),  FALSE );
02404         }
02405         else if( Active == 2 )
02406         {
02407             EnableGadget( _R(IDC_FILE_TYPE_LIST),   FALSE );
02408             EnableGadget( _R(IDC_FILE_TYPE_LIST2),  TRUE );
02409         }
02410     }
02411 }
02412 
02413 
02414 
02415 /***********************************************************************************************
02416 
02417 >   void BitmapExportPreviewDialog::DisplayZoomFactor()
02418 
02419     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02420     Created:    20/04/97
02421     Inputs:     None.
02422     Purpose:    Displays the zoom factor.
02423     Returns:    None.
02424                                                                  
02425 ***********************************************************************************************/
02426 
02427 void BitmapExportPreviewDialog::DisplayZoomFactor()
02428 {
02429     // get the "Selected" string
02430     String_32 Sel(_R(IDS_PREVIEW_SELECTED));
02431 
02432     // for the first image
02433     String_32 Str1;
02434     Str1.MakeMsg(_R(IDS_PREVIEW_IMAGEA), (UINT32)(m_ZoomFactor + 0.5));
02435     if (m_ActiveBitmap == 1)
02436     {
02437         Str1 += Sel;
02438         EnableGadget(_R(IDC_ACTIVE1), TRUE);
02439     }
02440     else
02441         EnableGadget(_R(IDC_ACTIVE1), FALSE);
02442 
02443     SetStringGadgetValue(_R(IDC_ACTIVE1),Str1);
02444     InvalidateGadget(_R(IDC_FILE_TYPE_LIST)); // so the outline is not drawn over the top of the drop down
02445 
02446     // for the second image
02447     Str1.MakeMsg(_R(IDS_PREVIEW_IMAGEB), UINT32(m_ZoomFactor * m_Scaling + 0.5));
02448     if (m_ActiveBitmap == 2)
02449     {
02450         Str1 += Sel;
02451         EnableGadget(_R(IDC_ACTIVE2), TRUE);
02452     }
02453     else
02454         EnableGadget(_R(IDC_ACTIVE2), FALSE);
02455 
02456     SetStringGadgetValue(_R(IDC_ACTIVE2),Str1);
02457     InvalidateGadget(_R(IDC_FILE_TYPE_LIST2)); // so the outline is not drawn over the top of the drop down
02458 
02459     DisplayBitmapInfo();
02460 }
02461 
02462 
02463 
02464 
02465 /********************************************************************************************
02466 
02467 >   void BitmapExportPreviewDialog::DisplayBitmapInfo()
02468 
02469     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02470     Created:    10/5/97
02471     Inputs:     -
02472     Outputs:    -
02473     Returns:    -
02474     Purpose:    Displays the file and image sizes and the file size difference between the 
02475                 two bitmaps
02476 ********************************************************************************************/
02477 
02478 void BitmapExportPreviewDialog::DisplayBitmapInfo()
02479 {
02480     if ((BitmapData[0].m_pBitmap == NULL) || (BitmapData[1].m_pBitmap == NULL))
02481     {
02482         // no bitmap yet
02483         EnableGadget(_R(IDC_IMAGESIZE1), FALSE);
02484         EnableGadget(_R(IDC_IMAGESIZE2), FALSE);
02485         EnableGadget(_R(IDC_FILESIZE1), FALSE);
02486         EnableGadget(_R(IDC_FILESIZE2), FALSE);
02487         HideGadget(_R(IDC_FILEDIFF1), TRUE);
02488         HideGadget(_R(IDC_FILEDIFF2), TRUE);
02489         return;
02490     }
02491 
02492     EnableGadget(_R(IDC_IMAGESIZE1), m_ActiveBitmap == 1);
02493     EnableGadget(_R(IDC_IMAGESIZE2), m_ActiveBitmap == 2);
02494     EnableGadget(_R(IDC_FILESIZE1), m_ActiveBitmap == 1);
02495     EnableGadget(_R(IDC_FILESIZE2), m_ActiveBitmap == 2);
02496 
02497     String_64 ImageSize;
02498     String_64 FileSize;
02499     
02500     // for the first image
02501     BitmapData[0].GenerateBitmapInfoStrings(ImageSize, FileSize, TRUE);
02502     SetStringGadgetValue(_R(IDC_IMAGESIZE1), ImageSize);
02503     SetStringGadgetValue(_R(IDC_FILESIZE1), FileSize);
02504 
02505     // for the second image
02506     BitmapData[1].GenerateBitmapInfoStrings(ImageSize, FileSize, TRUE);
02507     SetStringGadgetValue(_R(IDC_IMAGESIZE2), ImageSize);
02508     SetStringGadgetValue(_R(IDC_FILESIZE2), FileSize);
02509 
02510     // now set the file difference
02511 
02512     // calc the file difference
02513     INT32 diff = BitmapData[0].m_FileSize - BitmapData[1].m_FileSize;
02514 
02515     // display only for the selected bitmap
02516     HideGadget(_R(IDC_FILEDIFF1), m_ActiveBitmap != 1);
02517     HideGadget(_R(IDC_FILEDIFF2), m_ActiveBitmap != 2);
02518 
02519     String_64 FileDiff(_R(IDS_FILE_DIFF));
02520 
02521     if (diff != 0)
02522     {
02523         String_32 s;
02524         s.MakeMsg(_R(IDS_FILE_DIFF_BYTES), abs(diff));
02525         FileDiff += s;
02526     }
02527 
02528     if (m_ActiveBitmap == 1)
02529     {
02530         if (diff > 0)
02531             FileDiff += String_16(_R(IDS_LARGER));
02532         else if (diff < 0)
02533             FileDiff += String_16(_R(IDS_SMALLER));
02534         else
02535             FileDiff += String_16(_R(IDS_SAMESIZE));
02536 
02537         SetStringGadgetValue(_R(IDC_FILEDIFF1),FileDiff);
02538     }
02539     else
02540     {
02541         if (diff < 0)
02542             FileDiff += String_16(_R(IDS_LARGER));
02543         else if (diff > 0)
02544             FileDiff += String_16(_R(IDS_SMALLER));
02545         else
02546             FileDiff += String_16(_R(IDS_SAMESIZE));
02547 
02548         SetStringGadgetValue(_R(IDC_FILEDIFF2),FileDiff);
02549     }
02550 }
02551 
02552     
02553 /********************************************************************************************
02554 
02555 >   BOOL BitmapExportPreviewDialog::OnExport(BitmapExportOptions * pExportOptions)
02556 
02557     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02558     Created:    10/5/97
02559     Inputs:     Num - in which preview box to set the bitmap (either 1, or 2)
02560     Outputs:    -
02561     Returns:    -
02562     Purpose:    Alows export of the document into a temp file to be requested on 
02563                 pressing the Export button in the dialog.
02564 ********************************************************************************************/
02565 
02566 BOOL BitmapExportPreviewDialog::OnExport(BitmapExportOptions * pExportOptions)
02567 {
02568     // remember the active bitmap
02569     UINT32 Num = m_ActiveBitmap;
02570 
02571     // if first time call - set the first bitmap
02572     if (Num == 0)
02573         Num = 1;
02574 
02575     // check for bitmap filter
02576 //  if (m_pBmpFilter == NULL)
02577 //      return FALSE;
02578 
02579     if (pExportOptions == NULL)
02580         return FALSE;
02581 
02582     //  Compare the new options with the old ones. Also look at the m_bUseExistingPalette
02583     //  to see if we should use the existing palette.
02584 /*  if ( ((pCurrentOptions != NULL)&& (pCurrentOptions->Equal(pExportOptions))) && !BmapPrevDlg::m_bUseExistingPalette 
02585         && ( BmapPrevDlg::m_nTransColour ) < 0 )
02586     {
02587         // the same options => do nothing
02588         return TRUE;  
02589     }
02590 */
02591     // we want to keep a copy of the options, so make one
02592     //BitmapExportOptions *pOptions = pExportOptions->MakeCopy();
02593 
02594     // export and import back 
02595     //BOOL ok = DoWithExportOptions(pOptions, Num);
02596 
02597     BOOL ok = DoWithExportOptions(pExportOptions, Num);
02598 
02599     if (ok)
02600     {
02601         // everything went ok, so
02602         // store the temp file in the options passed to us
02603 //      pExportOptions->CopyFrom(BitmapData[m_ActiveBitmap-1].m_pOptions);
02604     }
02605 /*  else
02606     {
02607         // get rid of the temp options
02608         delete pOptions;
02609     }
02610 */
02611     return ok;
02612 }
02613 
02614 
02615 /******************************************************************************************
02616 
02617 >   void BitmapExportPreviewDialog::InitialiseBitmapPaletteInformation( BitmapExportOptions* pExportOptions, 
02618                 INT32 Num = 0 )
02619 
02620     Author:     Alex_Price (Xara Group Ltd) <camelotdev@xara.com>
02621 
02622     Created:    17/08/99
02623 
02624     Inputs:     pExportOptions - The export options containing the palette information
02625                 Num - If the default value of 0 is used here, then information is copied
02626                 over to both preview images. If the value of Num is < 0, then only the 
02627                 active bitmap is updated.
02628 
02629     Returns:    -
02630 
02631     Purpose:    Copies the palette information to the preview image information block. Depending
02632                 on the value of 'Num' passed in, then either the currently active bitmap,
02633                 or both the bitmaps are updated.
02634 
02635 ******************************************************************************************/
02636 
02637 void BitmapExportPreviewDialog::InitialiseBitmapPaletteInformation( BitmapExportOptions* pExportOptions, INT32 Num )
02638 {
02639     if( Num < 0 )
02640     {
02641         if( BitmapData[ m_ActiveBitmap - 1 ].m_pOptions )
02642             BitmapData[ m_ActiveBitmap - 1 ].m_pOptions->CopyFrom( pExportOptions );
02643     }
02644     else
02645     {
02646         if( BitmapData[ 0 ].m_pOptions )
02647             BitmapData[ 0 ].m_pOptions->CopyFrom( pExportOptions );
02648         if( BitmapData[ 1 ].m_pOptions )
02649             BitmapData[ 1 ].m_pOptions->CopyFrom( pExportOptions );
02650     }
02651 }
02652 
02653 
02654 /********************************************************************************************
02655 
02656 >   BOOL BitmapExportPreviewDialog::DoWithExportOptions(BitmapExportOptions *pExportOptions, 
02657             UINT32 Num)
02658 
02659     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
02660     Created:    10/5/97
02661     Inputs:     pExportOptions - pointer to bitmap export options
02662                 Num - in which preview box to set the bitmap (either 1, or 2)
02663     Outputs:    -
02664     Returns:    TRUE if successful, FALSE otherwise
02665     Purpose:    Receives bitmap export options, which are passed to the export filter to export 
02666                 the document into a temporary disk file. This file is then imported back to be 
02667                 displayed in one of the preview rectangles. 
02668 ********************************************************************************************/
02669 
02670 BOOL BitmapExportPreviewDialog::DoWithExportOptions(BitmapExportOptions *pOptions, UINT32 Num)
02671 {
02672     ERROR3IF(pOptions == NULL,"NULL Export options parameter passed");
02673     ERROR3IF((Num != 1) && (Num != 2), "Invalid num of preview rectangle passed");
02674 
02675 /*  // set the filter to match the new options
02676     // if it hasn't been set for some reason
02677 
02678   if (m_pBmpFilter == NULL)
02679         m_pBmpFilter = pOptions->FindBitmapFilterForTheseExportOptions();
02680 */
02681     // test for bitmap filter
02682     if ((m_pBmpFilter == NULL) || (!m_pBmpFilter->IS_KIND_OF(BaseBitmapFilter)))
02683     {
02684         InformError(_R(IDT_CANT_FIND_FILTER));
02685         return FALSE;
02686     }
02687 
02688     // create a disk file
02689     CCDiskFile TempDiskFile(1024, FALSE, TRUE);
02690     
02691     // create a temp file 
02692     PathName TempPath = FileUtil::GetTemporaryPathName();
02693 
02694     // If we want any change of re-importing IM based filters, they need an extension
02695     if( m_pBmpFilter->GetFilterType() == IMAGEMAGICK )
02696         TempPath.SetType( ((ImageMagickFilter*)m_pBmpFilter)->GetExtension() );
02697 
02698 // Set flag telling exporter that we are NOT exporting a temporary file!
02699 pOptions->SetTempFileFlag(TRUE);
02700 
02701     BOOL ok = TRUE;
02702 
02703     Progress    SlowJob;
02704 
02705     try  // to export the document to the temp file
02706     {
02707         //no need for preview bitmap
02708         m_pBmpFilter->IncludePreviewBmp(FALSE);
02709 
02710         // try to export the document
02711         BOOL ExportedOK = TRUE;
02712 
02713         if (pOptions->GetSelectionType() != ABITMAP)
02714         {
02715             // export the document
02716             ExportedOK = m_pBmpFilter->DoExportWithOptions(this, &TempDiskFile, &TempPath, 
02717                                                     Document::GetCurrent(), pOptions);
02718         }
02719         else
02720         {
02721             ERROR3IF(!pOptions->IS_KIND_OF(JPEGExportOptions),"Bad bitmap export options type");
02722             JPEGExportOptions *pJPEGOptions = (JPEGExportOptions *)pOptions;
02723 
02724             // get the bitmap to export from the options
02725             KernelBitmap* pBitmap = pJPEGOptions->GetKernelBitmap();
02726             
02727             if (pBitmap != NULL)
02728             {
02729                 // export the bitmap
02730                 ExportedOK = ((JPEGExportFilter *)m_pBmpFilter)->DoExportBitmapWithOptions(this, 
02731                                                 &TempDiskFile, &TempPath, pBitmap, pJPEGOptions);
02732 
02733                 //restore the pointer to the bitmap, which got cleared during the export
02734                 if (ExportedOK)
02735                     pJPEGOptions->SetKernelBitmap(pBitmap);
02736             }
02737             else
02738             {
02739                 ok = FALSE;
02740             }
02741         }
02742 
02743         if (!ExportedOK)
02744         {
02745             UINT32 ErrNo = Error::GetErrorNumber();
02746             // Something went a bit wrong - tell the user what it was.
02747             // Supress the error if it was the 'user has cancelled one'
02748             if ((ErrNo != _R(IDN_USER_CANCELLED)) && ( ErrNo != _R(IDW_CANCELEXPORT)))
02749             {
02750                 InformError();
02751                 m_pBmpFilter->DeleteExportFile(&TempDiskFile);
02752             }
02753             else
02754             {
02755                 // otherwise remove the error so it won't get reported
02756                 Error::ClearError();
02757             }
02758 
02759             return FALSE;
02760         }
02761     }
02762     // See if there was a file io error
02763     catch( CFileException )
02764     {
02765         UINT32 ErrNo = Error::GetErrorNumber();
02766         // Report the error if no one else did
02767         if ((ErrNo != _R(IDN_USER_CANCELLED)) && (ErrNo != _R(IDW_CANCELEXPORT)) && 
02768             (ErrNo != _R(IDW_CANCELLEDBMPEXPORT)))
02769         {
02770             InformError();
02771         }
02772         else
02773             Error::ClearError();    // otherwise remove the error so it won't get reported
02774 
02775         // Make sure that the file is closed and deleted
02776         try
02777         {
02778             // First try and delete it (tries to close it first)
02779             if (m_pBmpFilter)
02780                 m_pBmpFilter->DeleteExportFile(&TempDiskFile);
02781 
02782             // Double check to make sure it is closed.
02783             if (TempDiskFile.isOpen())
02784                 TempDiskFile.close();
02785         }
02786         catch( CFileException )
02787         {
02788             // Failed to close the file - not much we can do about it really
02789         }
02790 
02791         return FALSE;
02792     }
02793 
02794     if (ok)
02795     {
02796         // try to import the temporary file
02797 
02798         // close it first 
02799         if (TempDiskFile.isOpen())
02800             TempDiskFile.close();
02801 
02802         // open it back for reading
02803         ok = TempDiskFile.open(TempPath, ios::in | ios::binary);
02804 
02805         // Make sure we have a generic filter!
02806         GenericFilter *pGenericFilter = Filter::GetGenericFilter();
02807 
02808         if (ok && pGenericFilter != NULL)
02809         {
02810             // remember the file size
02811             UINT32 FileSize = TempDiskFile.Size();
02812 
02813             // find the best filter for the import
02814             Filter *pImportFilter = pGenericFilter->GetBestFilter(&TempDiskFile);
02815             KernelBitmap *pKernelBitmap;
02816 
02817             // we only handle bitmap filters
02818             if (pImportFilter && !pImportFilter->IS_KIND_OF(BaseBitmapFilter))
02819             {
02820                 // not a bitmap filter 
02821                 pImportFilter = NULL;
02822             }
02823 
02824             // import the file
02825             if (pImportFilter != NULL)
02826             {
02827                 // Setup import DPI from export options (this means we get the same resolution bitmap from
02828                 // a PDF)
02829                 ((BaseBitmapFilter *)pImportFilter)->SetImportDPI( pOptions->GetDPI() );
02830 
02831                 // Set the preview bitmap flag to avoid adding the bitmap to the global bitmap list
02832                 ((BaseBitmapFilter *)pImportFilter)->SetPreviewBitmap(TRUE);
02833 
02834                 ok = pImportFilter->ImportBitmap(&TempDiskFile, &pKernelBitmap);
02835 
02836                 // Set it back
02837                 ((BaseBitmapFilter *)pImportFilter)->SetPreviewBitmap(FALSE);
02838 
02839                 // close the file
02840                 TempDiskFile.close();
02841 
02842                 if (ok)
02843                 {
02844                     // check if the bitmap is the same size, so the current view can be preserved
02845                     BOOL NeedDefaultZoom = TRUE; 
02846                     KernelBitmap *pBmp = BitmapData[Num - 1].m_pBitmap;
02847 
02848                     if (pBmp != NULL)
02849                     {
02850                         if ((pKernelBitmap->GetRecommendedWidth() == pBmp->GetRecommendedWidth()) && 
02851                             (pKernelBitmap->GetRecommendedHeight() == pBmp->GetRecommendedHeight()))
02852                         NeedDefaultZoom = FALSE;
02853                     }
02854 
02855                     // if doing a "make bitmap copy" - use the memory instead of the file size
02856                     if ((m_pParentDlg != NULL) && (m_pParentDlg->m_FilterType == MAKE_BITMAP_FILTER))
02857                     {
02858                         // get the OIL bitmap
02859                         OILBitmap* pOILy = pKernelBitmap->GetActualBitmap();
02860 
02861                         // extract the bitmap size
02862                         if (pOILy != NULL)
02863                             FileSize =pOILy->GetBitmapSize();
02864                     }
02865 
02866                     String_256 oldTempPath = pOptions->GetPathName().GetPath();
02867                     if (pOptions->GetPathName().IsValid() && (oldTempPath != TempPath.GetPath()))
02868                     {
02869                         // Delete any old files that might be around
02870                         PathName        path( pOptions->GetPathName() );
02871                         FileUtil::DeleteFile( &path );
02872                     }
02873 
02874                     // set the new path name in the options object
02875                     pOptions->SetPathName(&TempPath);
02876 
02877                     // set the bitmap 
02878                     BitmapData[Num-1].SetNewBitmap(pKernelBitmap, FileSize, pOptions);
02879 
02880                     //  If we need to, make a copy of one of the Kernel bitmaps before 
02881                     //  transparency is turned on. This is done so that, when 1 or more colours
02882                     //  have been made transparent, then moving the mouse over the pixel in the
02883                     //  preview image highlights the colour 'underneath'
02884                     if( m_pParentDlg->m_pExportOptions->GetTransparencyIndex())
02885                     {
02886                         //  Preview image 'Num' has been made transparent.
02887                         //  If there is no KernelBitmap, then make one.
02888                         if( pOriginalBitmap[ Num - 1 ] == NULL )
02889                         {
02890                             if( m_bNeedBitmapCopied[ Num - 1 ] )
02891                             {
02892                                 pOriginalBitmap[ Num - 1 ] = new KernelBitmap( ( BitmapData[Num-1].m_pBitmap )->ActualBitmap );
02893                                 //  Make sure the following variable is set to the correct value.
02894                                 m_bNeedBitmapCopied[ Num - 1 ] = FALSE;
02895                             }
02896                         }
02897                         else
02898                         {
02899                             //  There has been a bitmap before. To determine whether we can use this
02900                             //  one or not, we look at the appropriate variable.
02901                             if( m_bNeedBitmapCopied[ Num - 1 ] )
02902                             {
02903                                 //  Need a new bitmap
02904                                 //  Get rid of the old one first.
02905                                 if( pOriginalBitmap[ Num - 1 ] )
02906                                 {
02907                                     delete pOriginalBitmap[ Num - 1 ];
02908                                     pOriginalBitmap[ Num - 1 ] = NULL;
02909                                 }
02910                                 pOriginalBitmap[ Num - 1 ] = new KernelBitmap( ( BitmapData[Num-1].m_pBitmap )->ActualBitmap );
02911                                 //  Don't need to do this again for the moment.
02912                                 m_bNeedBitmapCopied[ Num - 1 ] = FALSE;
02913                             }
02914                             else
02915                             {
02916                                 //  It is ok to use the existing bitmap, so we don't have to do
02917                                 //  anything else.
02918                             }
02919                         }
02920                     }
02921                     
02922                     // check if this is the first bitmap
02923                     if (BitmapData[2-Num].m_pBitmap == NULL)
02924                     {
02925                         // initialise the export options for the other side
02926                         // try to make them both the same and borrow the bitmap from the first side
02927                         BitmapExportOptions * pNewOptions = NULL;
02928 
02929                         UINT32 idString = pOptions->GetFilterNameStrID();
02930                         if( idString == _R(IDN_FILTERNAME_GIF) )
02931                             pNewOptions = new GIFExportOptions();
02932                         else
02933                         if( idString == _R(IDT_FILTERNAME_BMP) )
02934                             pNewOptions = new BMPExportOptions();
02935                         else
02936                         if( idString == _R(IDS_JPG_EXP_FILTERNAME) )
02937                             pNewOptions = new JPEGExportOptions();
02938                         else
02939 //                      if( idString == _R(IDS_FILTERNAME_PNG):
02940                             pNewOptions = new PNGExportOptions();
02941 
02942                         KernelBitmap * pNewKBMP = new KernelBitmap(pKernelBitmap->ActualBitmap);
02943 
02944                         if (pNewKBMP && pNewOptions)
02945                         {
02946                             pNewOptions->RetrieveDefaults();
02947                             pNewOptions->CopyFrom(pOptions);
02948 
02949                             // set the other bitmap data to be the same
02950                             BitmapData[2-Num].SetNewBitmap(pNewKBMP, FileSize, pNewOptions);
02951 
02952                             // clear the flags for same bitmap
02953                             BitmapData[0].m_bIsSameBitmap = FALSE;
02954                             BitmapData[1].m_bIsSameBitmap = FALSE;
02955                         }
02956                         else
02957                             BitmapData[2-Num].SetNewBitmap(pKernelBitmap, FileSize, pOptions);
02958 
02959                     }
02960                     else
02961                     {
02962                         // clear the flags for same bitmap
02963                         BitmapData[0].m_bIsSameBitmap = FALSE;
02964                         BitmapData[1].m_bIsSameBitmap = FALSE;
02965                     }
02966 
02967                     if (BitmapData[0].m_pBitmap != NULL)
02968                     {
02969                         // remember some bitmap info
02970                         m_Width  = BitmapData[0].m_pBitmap->GetRecommendedWidth();
02971                         m_Height = BitmapData[0].m_pBitmap->GetRecommendedHeight();
02972                         if (m_Width  < 1) m_Width  = 1;
02973                         if (m_Height < 1) m_Height = 1;
02974 
02975                         // remember the scaling between the two bitmaps 
02976                         // (assuming the aspect ratio is the same)
02977                         MILLIPOINT WidthB = BitmapData[1].m_pBitmap->GetRecommendedWidth();
02978                         if (WidthB < 1) 
02979                             WidthB = 1;
02980                         m_Scaling = (double) m_Width / WidthB;
02981 
02982                         // set the active bitmap
02983                         ChangeActiveBitmap(Num);
02984 
02985                         // display info for the bitmap
02986                         DisplayBitmapInfo();
02987 
02988                         // calculate new view if necessary
02989                         if (NeedDefaultZoom)
02990                         {
02991                             // do the default zoom
02992                             CalcViewRect(-1, NULL); // calculate initial view
02993                             
02994                             // zoom the new rectangle to 100% 
02995                             if (Num == 1)
02996                                 CalcViewRect(100, NULL);
02997                             else 
02998                                 CalcViewRect(100 / m_Scaling, NULL);
02999                             PaintGadgetNow(_R(IDC_REDRAW1));
03000                             PaintGadgetNow(_R(IDC_REDRAW2));
03001                         }
03002                         else
03003                         {
03004                             // Render the controls
03005                             InvalidateGadget(_R(IDC_REDRAW1));
03006                             InvalidateGadget(_R(IDC_REDRAW2));
03007                             PaintGadgetNow( _R(IDC_REDRAW1) );
03008                             PaintGadgetNow( _R(IDC_REDRAW2) );
03009                         
03010                         }
03011 
03012                         return TRUE;
03013                     }
03014                 }
03015 
03016                 if (!ok) // failed to import the file properly
03017                 {
03018                     UINT32 ErrNo = Error::GetErrorNumber();
03019                     // Something went a bit wrong - tell the user what it was.
03020                     // Supress the error if it was the 'user has cancelled one'
03021                     if ((ErrNo != _R(IDN_USER_CANCELLED)) && (ErrNo != _R(IDW_CANCELLEDBMPIMPORT)))
03022                     {
03023                         InformError();
03024                     }
03025                     else
03026                     {
03027                         // otherwise remove the error so it won't get reported
03028                         Error::ClearError();
03029                     }
03030                 }
03031             }
03032         }
03033     }
03034 
03035     // We don't need to report this error since, it's reported indirectly in the 
03036     // preview bitmap areas
03037     Error::ClearError();
03038 
03039     // the operation failed
03040     return FALSE;
03041 }
03042 
03043 
03044 /********************************************************************************************
03045 
03046 >   void BitmapExportPreviewDialog::DoCommand(StringBase *CommandID)
03047 
03048     Author:     Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
03049     Created:    10/5/97
03050     Inputs:     CommandID - the token of the menu selected command 
03051     Outputs:    -
03052     Returns:    -
03053     Purpose:    Called when a menu command is selected to perform the respective operation
03054 ********************************************************************************************/
03055 
03056 void BitmapExportPreviewDialog::DoCommand(StringBase *CommandID)
03057 {
03058     if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_ZOOM_TOOL)
03059         OnZoomTool(); // "Zoom Tool"
03060     else if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_PUSH_TOOL)
03061         OnPushTool(); // "Push Tool"
03062     else if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_COLOUR_SELECTOR_TOOL)
03063         OnColourSelectorTool(); // 'Colour Selector'
03064     else if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_ZOOM_TO_FIT)
03065         CalcViewRect(-1, NULL); //"Zoom to Fit"
03066     else if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_ZOOM_TO_100)
03067         On100Percent(); // "Zoom to 100%"
03068     else if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_1TO1)
03069         On1to1(); // "Zoom to 100%"
03070     else if (*CommandID == (PCTSTR)OPTOKEN_PREVIEW_HELP)
03071     {
03072         // call the parent dialog to do the help 
03073         if (m_pParentDlg != NULL)
03074             m_pParentDlg->OnHelpButtonClicked();
03075     }
03076 }

Generated on Sat Nov 10 03:44:28 2007 for Camelot by  doxygen 1.4.4