// $Id: optspage.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // Implementation of the Page tab of the options dialog box /* */ #include "camtypes.h" #include "appprefs.h" //#include "prefsdlg.h" // dialog/gadget ids //#include "optsres.h" // error strings #include "optspage.h" #include "optsmsgs.h" //#include "app.h" // Camelot object - in camtypes.h [AUTOMATICALLY REMOVED] //#include "document.h" // document object - in camtypes.h [AUTOMATICALLY REMOVED] //#include "spread.h" // spread object - in camtypes.h [AUTOMATICALLY REMOVED] #include "page.h" // page object //#include "units.h" // units - in camtypes.h [AUTOMATICALLY REMOVED] #include "pagesize.h" // Page sizes available e.g. A4 //#include "trans2d.h" // 2d translation matrix - in camtypes.h [AUTOMATICALLY REMOVED] #include "layer.h" #include "progress.h" // Begin/EndSlowJob CC_IMPLEMENT_DYNAMIC(PageTab, OptionsTabs) CC_IMPLEMENT_DYNCREATE(OpPageResize, UndoableOperation) CC_IMPLEMENT_DYNCREATE(ActionPageResize, Action) // This is not compulsory, but you may as well put it in so that the correct version // of your file can be registered in the .exe DECLARE_SOURCE("$Revision: 1282 $"); // Set some limit to the allowed page dimensions so that cannot have stupid values // better to do this than fall over or stop rendering. // The maximum at present which we can cope with is about 2.75M. // This was determined by trial and error, and is the maximum page size that allows an // object to be placed in the Top-Right corner, without our Render Matrix overflowing // at maximum zoom (and hence the object not rendering). // Future versions of Xara, should probably dynamically limit the Zoom factor to stop this. // but limiting the Page size is easiest for now. //const MILLIPOINT MaxPageDimension = 12 * 72000 * 12; // maximum = 12ft const MILLIPOINT MaxPageDimension = 9 * 72000 * 12; // maximum = 108in = 9 ft = 275cm const MILLIPOINT MinPageDimension = 72000/2; // minimum = 0.5inch /******************************************************************************************** > PageTab::PageTab() Author: Neville_Humphrys (Xara Group Ltd) Created: 7/12/94 Inputs: - Outputs: - Returns: - Purpose: PageTab constructor. Creates a non-undoable operation Errors: - SeeAlso: - ********************************************************************************************/ PageTab::PageTab() { // Do nothing for now InitedPageSizeList = FALSE; } /******************************************************************************************** > PageTab::~PageTab() Author: Neville_Humphrys (Xara Group Ltd) Created: 7/12/94 Inputs: - Outputs: - Returns: - Purpose: PageTab destructor Errors: - SeeAlso: - ********************************************************************************************/ PageTab::~PageTab() { } /******************************************************************************************** > BOOL PageTab::Init() Author: Neville_Humphrys (Xara Group Ltd) Created: 7/12/94 Inputs: - Outputs: - Returns: True if initialised ok, False if failed. Purpose: PageTab initialisation routine Errors: - SeeAlso: - ********************************************************************************************/ BOOL PageTab::Init() { // Init (register) all our undoable operations if (!OpPageResize::Init()) return(FALSE); return TRUE; } /****************************************************************************************** > CDlgResID PageTab::GetPageID()() Author: Neville_Humphrys (Xara Group Ltd) Created: 7/12/94 Inputs: - Outputs: - Returns: The dialog ID of this tab section. Purpose: Allows the options dialog code to determine the dialog ID of this section. Errors: - SeeAlso: - ******************************************************************************************/ CDlgResID PageTab::GetPageID() { return _R(IDD_OPTSTAB_PAGE); } /****************************************************************************************** > BOOL PageTab::IsDocumentOption() Author: Neville_Humphrys (Xara Group Ltd) Created: 14/12/94 Inputs: - Outputs: - Returns: Returns True if this tab is a document option. Purpose: Allows the document options dialog code to determine if this tab belongs to the group of document options. Errors: - SeeAlso: IsProgramOption(); ******************************************************************************************/ BOOL PageTab::IsDocumentOption() { return TRUE; // This tab is not a document option } /****************************************************************************************** > BOOL PageTab::IsProgramOption() Author: Neville_Humphrys (Xara Group Ltd) Created: 14/12/94 Inputs: - Outputs: - Returns: Returns True if this tab is a program option. Purpose: Allows the program options dialog code to determine if this tab belongs to the group of program options. Errors: - SeeAlso: IsProgramOption(); ******************************************************************************************/ BOOL PageTab::IsProgramOption() { return TRUE; // This tab is a program option } /****************************************************************************************** > BOOL AppPrefsDlg::CommitSection() Author: Neville_Humphrys (Xara Group Ltd) Created: 7/12/94 Inputs: - Outputs: - Returns: True if values in dialog box ok, False otherwise. Purpose: Takes the values in the Page section tab of the options dialog box and sets the associated preference values accordingly Called when ok is pressed on the dialog box. Errors: - SeeAlso: - ******************************************************************************************/ BOOL PageTab::CommitSection() { TRACEUSER( "Neville", _T("commit page section\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::CommitSection called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The Page page identifier if (!ok) return TRUE; // Talk to page failed to return now // All units work off the selected document and so we must do nothing if there is no // selected document. Check our clas variable to see if this is true or not. // Units should have been set up by the caller. if (pDocument == NULL) return (TRUE); // Ok has been pressed so take the values from this section of the dialog box BOOL Valid=0; // Flag for validity of value // BOOL State=0; // Flag for state of button/switch // BOOL SetOk=0; // Preference value set ok // Section = Page // WEBSTER Neville 13/8/97 #ifdef WEBSTER // Webster has a limited set of controls. So use the present settings on the page and just // allow the user to alter the few parameters that they can. // Find out the details on the presently selected page/spread MILLIPOINT Width = 0; MILLIPOINT Height = 0; MILLIPOINT Margin = 0; MILLIPOINT Bleed = 0; BOOL Portrait = TRUE; BOOL Dps = FALSE; BOOL DropShadow = FALSE; INT32 PageSizeId =0; ok = GetSizeOfPage(&Width, &Height, &Margin, &Bleed, &Portrait, &Dps, &DropShadow); if (!ok) return FALSE; TRACEUSER( "Neville", _T("Currently Width =%d Height =%d Margin=%d Bleed=%d\n"), Width, Height, Margin, Bleed); #else // In Camelot mode, the user can change everything // First, get the current state of Portrait button BOOL Portrait = FALSE; Portrait = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), 0, 1, 0, &Valid); // Next, get the current values for the page width and height. // If custom use the editable fields otherwise use the actual page size from // the definition otherwise may encounter conversion errors. MILLIPOINT Width = 0; MILLIPOINT Height = 0; INT32 PageSizeSelected = CUSTOM; PageSizeSelected = pPrefsDlg->GetSelectedValueIndex(_R(IDC_OPTS_SIZELIST)); if (PageSizeSelected == CUSTOM) #endif //webster { // Portrait and landscape radio buttons should have been taken care of by the switch // changing the editable fields which we are just about to read. Height = pPrefsDlg->GetUnitGadgetValue(_R(IDC_OPTS_HEIGHT), CurrentPageUnits, MinPageDimension, MaxPageDimension, _R(IDE_OPTS_INVALIDHEIGHT), &Valid); if (!Valid) return FALSE; // height incorrect, user has been warned already Width = pPrefsDlg->GetUnitGadgetValue(_R(IDC_OPTS_WIDTH), CurrentPageUnits, MinPageDimension, MaxPageDimension, _R(IDE_OPTS_INVALIDWIDTH), &Valid); if (!Valid) return FALSE; // width incorrect, user has been warned already } // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER else { if (AppPrefsDlg::pPageSizesList != NULL && InitedPageSizeList) { // We will need to take account of the Portrait and landscape radio buttons and // hence swapping of the width and height fields as we are reading the values // directly from the sizes list. PageId PageChosen = (PageId)PageSizeSelected; AppPrefsDlg::pPageSizesList->GetSizeFromPageId(PageChosen, &Width, &Height); TRACEUSER( "Neville", _T("PageTab::CommitSection width %d height %d in MP\n"),Width,Height); // Now we have the width/height, check if landscape is selected and if so // swap the height and width over. if (!Portrait) { // Swap the height and width fields over. MILLIPOINT Temp = Width; Width = Height; Height = Temp; } } else { ERROR2IF(TRUE,FALSE,"Bad page sizes list in PageTab::CommitSection"); } } // Now the page margin size // Limit the page margin to much less than the page size as things like zoom to // spread/drawing assume that part of the spread is visible in the view so that // this can then be used to pick up the desired spread. MILLIPOINT Margin = 0; // MinPageDimension; MILLIPOINT MaxPageMargin = MaxPageDimension; Margin = pPrefsDlg->GetUnitGadgetValue(_R(IDC_OPTS_MARGIN), CurrentPageUnits, MinPageDimension, MaxPageMargin, 0, &Valid); if (Margin < 0 || Margin >= MaxPageDimension) // ignore valid as it will be false { InformError(_R(IDE_OPTS_INVALIDMARGIN)); return FALSE; // margin incorrect, user has been warned already } // Now the page bleed size MILLIPOINT Bleed = 0; BOOL BleedEnabled; BleedEnabled = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_BLEEDSWITCH), 0, 1, 0, &Valid); if (BleedEnabled) { const MILLIPOINT MaxBleed = (MILLIPOINT)(3 * 72000); // maximum in inches Bleed = pPrefsDlg->GetUnitGadgetValue(_R(IDC_OPTS_BLEED), CurrentPageUnits, 0, MaxBleed, _R(IDE_OPTS_INVALIDBLEED), &Valid); if (!Valid) return FALSE; // bleed incorrect, user has been warned already } else Bleed = 0; // Get current state of the double page spread button BOOL Dps = FALSE; Dps = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_DPS), 0, 1, 0, &Valid); // Get the current state of the drop shadow switch BOOL DropShadow = FALSE; DropShadow = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_SHADOW), 0, 1, 0, &Valid); #endif //webster // Check pasteboard dimensions // Possibly should get the resize operation to check this and pass back a result, as // loading dodgy documents might be possibly another way to create completely large pages. // Check if the overall size of the pasteboard will break our maximum dimensions MILLIPOINT PagesWidth = Width; if (Dps) PagesWidth += Width; // If double page spread then make two page wide MILLIPOINT PasteBoardWidth = Margin + PagesWidth + Margin; MILLIPOINT PasteBoardHeight = Margin + Height + Margin; if (PasteBoardWidth > MaxPageDimension || PasteBoardHeight > MaxPageDimension) { // There is a problem so warn the user that the value is incorrect InformWarning(_R(IDE_OPTS_OVERALLSPREADSIZE)); return FALSE; } // Go and make those requested changes // Now that we have the required information, now go and do it // Set up the parameters which we require to do the page resizing operation // This is undoable and redoable PageResizeInfo Param; // Set up the new page parameters that we want Param.Height = Height; Param.Width = Width; Param.Margin = Margin; Param.Bleed = Bleed; Param.Portrait = Portrait; Param.Dps = Dps; Param.ShowDropShadow = DropShadow; InvokeResize(&Param); return ok; } /****************************************************************************************** > BOOL PageTab::NewUnitsInSection() Author: Neville_Humphrys (Xara Group Ltd) Created: 5/1/95 Inputs: - Outputs: - Returns: True if values in dialog box ok, False otherwise. Purpose: Function called when new default units come into operation. We must convert all units fields to display in the newly specified units. Errors: - SeeAlso: - ******************************************************************************************/ BOOL PageTab::NewUnitsInSection() { TRACEUSER( "Neville", _T("New units in page section\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::NewUnitsInSection called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The page tab identifier if (!ok) return TRUE; // Talk to page failed to return now // All units work off the selected document and so we must do nothing if there is no // selected document. Check our clas variable to see if this is true or not. // Units should have been set up by the caller. if (pDocument == NULL) { // the dialog box is greyed. GreySection(); return (TRUE); } // Do the same things as the normal init section code InitPageSection(); return TRUE; } /******************************************************************************************** > BOOL PageTab::GreySection() Author: Neville_Humphrys (Xara Group Ltd) Created: 3/2/95 Inputs: - Outputs: - Returns: - Purpose: Called when the user has closed all documents Errors: - SeeAlso: PageTab::UngreySection; ********************************************************************************************/ BOOL PageTab::GreySection() { TRACEUSER( "Neville", _T("GreySection in page section\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::GreySection called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The page tab identifier if (!ok) return TRUE; // Talk to page failed to return now // Make sure the information field displaying the name of the current document // is correct. String_256 DocumentName(_R(IDT_OPTS_PAGE_INFO)); DocumentName += *GetDocumentName(); pPrefsDlg->SetStringGadgetValue(_R(IDC_OPTS_INFO), DocumentName); // Only update if we are not already grey if (GreyStatus == TRUE) return TRUE; // Call our central greying/ungreying function ok = ChangeControlStatus(FALSE); GreyStatus = TRUE; return ok; } /******************************************************************************************** > BOOL PageTab::UngreySection() Author: Neville_Humphrys (Xara Group Ltd) Created: 3/2/95 Inputs: - Outputs: - Returns: - Purpose: Called when the user has selected a new document Errors: - SeeAlso: PageTab::UngreySection; ********************************************************************************************/ BOOL PageTab::UngreySection() { TRACEUSER( "Neville", _T("UngreySection in page section\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::UngreySection called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The page tab identifier if (!ok) return TRUE; // Talk to page failed to return now // Make sure the information field displaying the name of the current document // is correct. String_256 DocumentName(_R(IDT_OPTS_PAGE_INFO)); DocumentName += *GetDocumentName(); pPrefsDlg->SetStringGadgetValue(_R(IDC_OPTS_INFO), DocumentName); // Only update if we are not already ungrey if (GreyStatus == FALSE) return TRUE; // Call our central greying/ungreying function ok = ChangeControlStatus(TRUE); GreyStatus = FALSE; return ok; } /******************************************************************************************** > BOOL PageTab::ChangeControlStatus(const BOOL Status) Author: Neville_Humphrys (Xara Group Ltd) Created: 3/2/95 Inputs: - Outputs: - Returns: - Purpose: Called to grey/ungrey all controls on this tab. Errors: - SeeAlso: PageTab::GreySection; PageTab::UngreySection; ********************************************************************************************/ BOOL PageTab::ChangeControlStatus(const BOOL Status) { // Grey/Ungrey the controls pPrefsDlg->EnableGadget(_R(IDC_OPTS_INFO), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_PAGEGROUP), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_SIZENAME), Status); pPrefsDlg->EnableGadget(_R(IDN_PAGESIZE_CUSTOM), Status); // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER pPrefsDlg->EnableGadget(_R(IDC_OPTS_SIZELIST), Status); #endif //webster pPrefsDlg->EnableGadget(_R(IDC_OPTS_HEIGHTTXT), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_HEIGHT), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_WIDTHTXT), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_WIDTH), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_ORIENTGROUP), Status); // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER pPrefsDlg->EnableGadget(_R(IDC_OPTS_PORTRAIT), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_LANDSCAPE), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_SPREADGROUP), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_MARGINTXT), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_MARGIN), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEEDSWITCH), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEED), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEEDTXT), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_DPS), Status); pPrefsDlg->EnableGadget(_R(IDC_OPTS_SHADOW), Status); #endif //webster return TRUE; } /******************************************************************************************** > BOOL PageTab::UpdateSection(String_256 *DocumentName) Author: Neville_Humphrys (Xara Group Ltd) Created: 3/2/95 Inputs: Name of document Outputs: - Returns: - Purpose: Called when we have switched to a new document and need to update all the controls on this tab. Should only init the tab if the page is present. The document name allows the info field on the tab to be filled in correctly. Errors: - SeeAlso: PageTab::GreySection; PageTab::UngreySection; PageTab::InitSection; ********************************************************************************************/ BOOL PageTab::UpdateSection(String_256 *DocumentName) { TRACEUSER( "Neville", _T("PageTab::UpdateSection\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::UpdateSection called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The Page page identifier if (!ok) return TRUE; // page not present // Do everything the same as the InitSection but do not init the page size list as this // causes a huge redraw. // Make sure the information field displaying the name of the current document // is correct. String_256 DocName(_R(IDT_OPTS_PAGE_INFO)); DocName += *DocumentName; pPrefsDlg->SetStringGadgetValue(_R(IDC_OPTS_INFO), DocName); // All units work off the selected document and so we must do nothing if there is no // selected document. Check our clas variable to see if this is true or not. // Units should have been set up by the caller. if (pDocument == NULL) { // If returns False then we are in an invalid situation and so should make sure that // the dialog box is greyed. GreySection(); return TRUE; } // Check if we have an uninitialised page sizes list if (!InitedPageSizeList) { // Set up the list of available page size options, starting with the default. // Handle everything that we do not know as a CUSTOM setting. SetUpPageSizeList(); } // Do the same things as the normal init section code InitPageSection(); return TRUE; } /******************************************************************************************** > BOOL PageTab::UpdatePageSection() Author: Neville_Humphrys (Xara Group Ltd) Created: 3/3/95 Inputs: - Outputs: - Returns: - Purpose: Called when we have undone a page resize operation and hence need to update the page's details on the page section of this tab. Should only init the tab if the page is present. Errors: - SeeAlso: PageTab::GreySection; PageTab::UngreySection; PageTab::InitSection; ********************************************************************************************/ BOOL PageTab::UpdatePageSection() { TRACEUSER( "Neville", _T("PageTab::UpdatePageSection\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::UpdatePageSection called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The Page page identifier if (!ok) return TRUE; // page not present // Do everything the same as the InitSection but do not init the page size list as this // causes a huge redraw. // All units work off the selected document and so we must do nothing if there is no // selected document. Check our clas variable to see if this is true or not. // Units should have been set up by the caller. if (pDocument == NULL) { // If returns False then we are in an invalid situation and so should make sure that // the dialog box is greyed. GreySection(); return (TRUE); } // Check if we have an uninitialised page sizes list if (!InitedPageSizeList) { // Remove any lists that we have created. //pPrefsDlg->DeleteAllValues(_R(IDC_OPTS_SIZELIST)); //InitedPageSizeList = FALSE; // Set up the list of available page size options, starting with the default. // Handle everything that we do not know as a CUSTOM setting. SetUpPageSizeList(); } // Call the normal init section code for the page parts return InitPageSection(); } /******************************************************************************************** > BOOL PageTab::HandleMsg(DialogMsg* Msg) Author: Neville_Humphrys (Xara Group Ltd) Created: 7/12/94 Inputs: - Outputs: - Returns: - Purpose: Handles all the Page options tabs messages Errors: - SeeAlso: - ********************************************************************************************/ BOOL PageTab::HandleMsg(DialogMsg* Msg) { TRACEUSER( "Neville", _T("HandlePageMsg\n")); ERROR2IF(Msg == NULL,FALSE,"PageTab::Message null message received"); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::HandleMsg called with no dialog pointer"); BOOL ok = pPrefsDlg->TalkToPage(_R(IDD_OPTSTAB_PAGE)); // The Page page identifier if (!ok) return TRUE; // page not present switch(Msg->DlgMsg) { case DIM_CREATE: // Initialise controls GreyStatus = FALSE; // we are ungreyed by default ok = InitSection(); if (!ok) InformError(); break; case DIM_SELECTION_CHANGED: OptionsTabs::SetApplyNowState(TRUE); // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER if (Msg->GadgetID == _R(IDC_OPTS_SIZELIST)) { // Get the currently selected item and set up the other fields accordingly INT32 PageSizeSelected; PageSizeSelected = pPrefsDlg->GetSelectedValueIndex(_R(IDC_OPTS_SIZELIST)); // Get whether we are in Portrait or Landscape mode BOOL Portrait; BOOL Valid; Portrait = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), 0, 1, 0, &Valid); HandlePageList(PageSizeSelected, Portrait); break; } case DIM_LFT_BN_CLICKED: OptionsTabs::SetApplyNowState(TRUE); if (FALSE) {} // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER else if ((Msg->GadgetID == _R(IDC_OPTS_PORTRAIT)) || (Msg->GadgetID == _R(IDC_OPTS_LANDSCAPE))) // Portrait landscape buttons toggle the width/height fields HandlePortraitLandscape(); #endif // Webster else if (Msg->GadgetID == _R(IDC_OPTS_BLEEDSWITCH)) { // Bleed switch enables or disables the bleed size field BOOL BleedEnabled; BOOL Valid; BleedEnabled = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_BLEEDSWITCH), 0, 1, 0, &Valid); if (BleedEnabled) { pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEED), TRUE); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEEDTXT), TRUE); } else { pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEED), FALSE); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEEDTXT), FALSE); } } #endif //webster case DIM_TEXT_CHANGED: OptionsTabs::SetApplyNowState(TRUE); break; default: break; } return TRUE; } /****************************************************************************************** > BOOL PageTab::InitSection() Author: Neville_Humphrys (Xara Group Ltd) Created: 6/12/94 Inputs: - Outputs: - Returns: TRUE if successful, else FALSE Purpose: Sets initial values for the Page section of the options dialog box. This section includes the:- Errors: - SeeAlso: AppPrefsDlg; OptionsTabs; UpdateSection; ******************************************************************************************/ BOOL PageTab::InitSection() { TRACEUSER( "Neville", _T("InitPageSection\n")); ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::InitSection called with no dialog pointer"); ERROR2IF(AppPrefsDlg::pPageSizesList == NULL,FALSE,"PageTab::InitSection called with list of page sizes"); // BOOL ok = TRUE; // Flag for whether value set up ok // We have an uninitialised page sizes list, so flag that before we have a chance to exit pPrefsDlg->DeleteAllValues(_R(IDC_OPTS_SIZELIST)); InitedPageSizeList = FALSE; // Do everything the same as the UpdateSection but init the page size list for this // once and only time to stop redraws. // Make sure the information field displaying the name of the current document // is correct. String_256 DocumentName(_R(IDT_OPTS_PAGE_INFO)); DocumentName += *GetDocumentName(); pPrefsDlg->SetStringGadgetValue(_R(IDC_OPTS_INFO), DocumentName); // All units work off the selected document and so we must do nothing if there is no // selected document. Check our clas variable to see if this is true or not. // Units should have been set up by the caller. if (pDocument == NULL) { // If returns False then we are in an invalid situation and so should make sure that // the dialog box is greyed. GreySection(); return (TRUE); } // Set up the list of available page size options, starting with the default. // Handle everything that we do not know as a CUSTOM setting. SetUpPageSizeList(); InitPageSection(); return TRUE; } /****************************************************************************************** > BOOL PageTab::SetUpPageSizeList() Author: Neville_Humphrys (Xara Group Ltd) Created: 30/3/95 Outputs: - Returns: TRUE if successful, else FALSE Purpose: Sets up the pages sizes list in the Page tab on the options dialog box. Done separately to InitPageSection so that code is modular and should only be used once when the page is set up and not on updates otherwise you get the drop list causing a huge redraw problem. Errors: - SeeAlso: InitSection; InitPageSection; AppPrefsDlg; OptionsTabs; ******************************************************************************************/ BOOL PageTab::SetUpPageSizeList() { // already set this up so don't do it again if (InitedPageSizeList) return TRUE; // Set up the list of available page size options, starting with the default. // Handle everything that we do not know as a CUSTOM setting. // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER pPrefsDlg->SetStringGadgetValue(_R(IDC_OPTS_SIZELIST), String_32(_R(IDN_PAGESIZE_CUSTOM))); #endif //webster // Now go through the defined list PageSize* pPageSize = (PageSize*) AppPrefsDlg::pPageSizesList->GetFirstPageSize(); while (pPageSize != NULL) { // Get the name of the current page size item String_32 *pPageName = pPageSize->GetPageName(); // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER pPrefsDlg->SetStringGadgetValue(_R(IDC_OPTS_SIZELIST), *pPageName); #endif //webster // skip to the next item, if there is one pPageSize = (PageSize*) AppPrefsDlg::pPageSizesList->GetNextPageSize(pPageSize); } // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER pPrefsDlg->SetComboListLength(_R(IDC_OPTS_SIZELIST)); #endif //webster // It is now set up and correct InitedPageSizeList = TRUE; return TRUE; } /****************************************************************************************** > BOOL PageTab::InitPageSection() Author: Neville_Humphrys (Xara Group Ltd) Created: 3/3/95 Outputs: - Returns: TRUE if successful, else FALSE Purpose: Sets initial values for the page details section of the Page tab on the options dialog box. Errors: - SeeAlso: InitSection; AppPrefsDlg; OptionsTabs; ******************************************************************************************/ BOOL PageTab::InitPageSection() { BOOL ok = TRUE; // Section = Page // List size done elsewhere so that only ever done once and not on updates as well. // Find out the details on the presently selected page/spread MILLIPOINT Width = 0; MILLIPOINT Height = 0; MILLIPOINT Margin = 0; MILLIPOINT Bleed = 0; PortraitSelected = TRUE; BOOL Dps = FALSE; // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER BOOL PageShadow = TRUE; #else BOOL PageShadow = FALSE; #endif //webster INT32 PageSizeId =0; ok = GetSizeOfPage(&Width, &Height, &Margin, &Bleed, &PortraitSelected, &Dps, &PageShadow); if (!ok) return FALSE; TRACEUSER( "Neville", _T("Width =%d Height =%d Margin=%d Bleed=%d\n"), Width, Height, Margin, Bleed); PageSizeId = GetPageSizeItem(Width, Height); TRACEUSER( "Neville", _T("PageSize =%d \n"), PageSizeId); // Set up the default option displayed // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER ok = pPrefsDlg->SetSelectedValueIndex(_R(IDC_OPTS_SIZELIST),PageSizeId); // Get the current portrait/landscape state orientation if ( PortraitSelected != FALSE ) { pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), TRUE); pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_LANDSCAPE), FALSE); } else { pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), FALSE); pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_LANDSCAPE), TRUE); } #endif //webster // Now set up and enable/disable the height and width fields accordingly // If not Portrait i.e. Landscape then swap the width and the height fields over if (PortraitSelected == FALSE) { // Swap width for height MILLIPOINT Temp = Width; Width = Height; Height = Temp; } // Now set up the height and width fields accordingly ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_HEIGHT), CurrentPageUnits, Height, FALSE, -1); ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_WIDTH), CurrentPageUnits, Width, FALSE, -1); BOOL Enable; // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER if (PageSizeId == CUSTOM) Enable = TRUE; else Enable = FALSE; #endif //webster // Enable should be True if the custom page size has been selected. pPrefsDlg->EnableGadget(_R(IDC_OPTS_HEIGHT), Enable); pPrefsDlg->EnableGadget(_R(IDC_OPTS_WIDTH), Enable); // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER // Now show the current page Margin ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_MARGIN), CurrentPageUnits, Margin, FALSE, -1); #endif //webster // Now show the current page bleed, setting or unsetting the switch accordingly // and greying/ungreying the size field accordingly. BOOL BleedEnabled; if (Bleed == 0) { // No bleed BleedEnabled = FALSE; } else { // Bleed present BleedEnabled = TRUE; } // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_BLEEDSWITCH), BleedEnabled); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEED), BleedEnabled); pPrefsDlg->EnableGadget(_R(IDC_OPTS_BLEEDTXT), BleedEnabled); #endif //webster // If the bleed is zero and disabled then fill in a default value of 3mm if ((Bleed == 0) && (!BleedEnabled)) { // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER Bleed = (MILLIPOINT)(3 * MM_MP_VAL); // 3mm in millipoints #else Bleed = 0; #endif //webster } // Now show the current value // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_BLEED), CurrentPageUnits, Bleed, FALSE, -1); // Now for the double page spread button pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_DPS), Dps); // Now for the show page shadow pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_SHADOW), PageShadow); #endif //webster return TRUE; } /****************************************************************************************** > INT32 PageTab::GetPageSizeItem(const MILLIPOINT Width, const MILLIPOINT Height) Author: Neville_Humphrys (Xara Group Ltd) Created: 9/12/94 Inputs: Width width of current page in millipoints Height height of current page in millipoints Outputs: Type of page found according to position on list Returns: - Purpose: Translates a width or height into a number which specifies whether it is A0, A1 ... or custom which corresponds to the list offered to the user. Errors: - SeeAlso: - ******************************************************************************************/ INT32 PageTab::GetPageSizeItem(const MILLIPOINT Width, const MILLIPOINT Height) { PageId ItemInList = CUSTOM; // set useful default of CUSTOM if (AppPrefsDlg::pPageSizesList != NULL) { // Use the PageSize and PageSizesList classes to work out if this is a known page // size or if it is regarded as a custom one. ItemInList = AppPrefsDlg::pPageSizesList->GetPageIdFromSize(Width, Height); TRACEUSER( "Neville", _T("PageTab::GetPageSizeItem width %d height %d give item = %d\n"),Width,Height,ItemInList); } return (INT32) ItemInList; } /****************************************************************************************** > BOOL PageTab::HandlePageList(INT32 ItemClicked, BOOL Portrait) Author: Neville_Humphrys (Xara Group Ltd) Created: 9/12/94 Inputs: ItemClicked number of item clicked in list Portrait True if Portrait, False if Landscape. Outputs: - Returns: - Purpose: Sets up the height and width fields according to the item selected in the list. Errors: - SeeAlso: - ******************************************************************************************/ BOOL PageTab::HandlePageList(INT32 ItemClicked, BOOL Portrait) { ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::HandlePageList called with no dialog pointer"); // Now enable or disable and fill in the height and width fields dependent // on what size has been selected in the list of available pages. BOOL Enable; BOOL ok; MILLIPOINT Width = 0; MILLIPOINT Height = 0; if ( ItemClicked == CUSTOM) { // If custom then just ungrey the present width/height editable fields Enable = TRUE; } else { Enable = FALSE; PageId PageChosen = (PageId)ItemClicked; if (AppPrefsDlg::pPageSizesList != NULL) { AppPrefsDlg::pPageSizesList->GetSizeFromPageId(PageChosen, &Width, &Height); TRACEUSER( "Neville", _T("PageTab::HandlePageList width %d height %d in MP\n"),Width,Height); } // If not Portrait i.e. Landscape then swap the width and the height fields over if (Portrait == FALSE) { // Swap width for height MILLIPOINT Temp = Width; Width = Height; Height = Temp; } // Now set up the height and width fields accordingly ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_HEIGHT), CurrentPageUnits, Height, FALSE, -1); ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_WIDTH), CurrentPageUnits, Width, FALSE, -1); } // Enable should be True if the custom page size has been selected. pPrefsDlg->EnableGadget(_R(IDC_OPTS_HEIGHT), Enable); pPrefsDlg->EnableGadget(_R(IDC_OPTS_WIDTH), Enable); return TRUE; } /****************************************************************************************** > BOOL PageTab::HandlePortraitLandscape() Author: Neville_Humphrys (Xara Group Ltd) Created: 9/12/94 Purpose: Checks to see if Portrait or Landscape has been selected. If a change has been made then swaps the height and width fields over. Errors: - SeeAlso: - ******************************************************************************************/ // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER BOOL PageTab::HandlePortraitLandscape() { ERROR2IF(pPrefsDlg == NULL,FALSE,"PageTab::HandlePortraitLandscape called with no dialog pointer"); // Get current state of Portrait button BOOL Portrait; BOOL Valid; Portrait = pPrefsDlg->GetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), 0, 1, 0, &Valid); // Check for change of state, if none then exit now if (Portrait == PortraitSelected) return TRUE; TRACEUSER( "Neville", _T("PageTab::HandlePortraitLandscape() change state\n")); // We have changed so swap the height and the width fields over // First, get the current values from the editable fields MILLIPOINT Width = 0; MILLIPOINT Height = 0; BOOL ok; Height = pPrefsDlg->GetUnitGadgetValue(_R(IDC_OPTS_HEIGHT), CurrentPageUnits, 0, INT_MAX, _R(IDE_OPTS_INVALIDHEIGHT), &Valid); if (!Valid) { // failed to read correct value so return switch to known position and exit pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), PortraitSelected); pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_LANDSCAPE), !PortraitSelected); return FALSE; } Width = pPrefsDlg->GetUnitGadgetValue(_R(IDC_OPTS_WIDTH), CurrentPageUnits, 0, INT_MAX, _R(IDE_OPTS_INVALIDWIDTH), &Valid); if (!Valid) { // failed to read correct value so return switch to known position and exit pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_PORTRAIT), PortraitSelected); pPrefsDlg->SetLongGadgetValue(_R(IDC_OPTS_LANDSCAPE), !PortraitSelected); return FALSE; } // Now set up the height and width fields reversly ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_HEIGHT), CurrentPageUnits, Width, FALSE, -1); ok = pPrefsDlg->SetUnitGadgetValue(_R(IDC_OPTS_WIDTH), CurrentPageUnits, Height, FALSE, -1); // Now update the stored present state to the new state PortraitSelected = Portrait; return TRUE; } #endif //webster /****************************************************************************************** > BOOL PageTab::GetSizeOfPage(MILLIPOINT *Width, MILLIPOINT *Height, MILLIPOINT *Bleed, BOOL *Portrait, BOOL *Dps, BOOL *ShowDropShadow) Author: Neville_Humphrys (Xara Group Ltd) Created: 9/12/94 Outputs: Width found page width in millipoints Height found page height in millipoints Margin found page margin in millipoints Bleed found page bleed in millipoints Portrait set TRUE if found Width smaller than height Dps set TRUE if double page spread present ShowDropShadow set TRUE if currently displaying a drop shadow Returns: True if found the details ok. Purpose: Checks to see what the size of the first page in the first spread in the document is and returns the width and height of it. Assumes at present a fairly simple document structure. Assumes the class variables pDocument, pSpread have been set up. Errors: - SeeAlso: AppPrefsDlg::SetCurrentSpread; ******************************************************************************************/ BOOL PageTab::GetSizeOfPage(MILLIPOINT *Width, MILLIPOINT *Height, MILLIPOINT *Margin, MILLIPOINT *Bleed, BOOL *Portrait, BOOL *Dps, BOOL *ShowDropShadow) { // Set up defaults in case of dodgy exit *Width = 0; *Height = 0; *Margin = 0; *Bleed = 0; *Portrait = TRUE; *Dps = FALSE; // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER *ShowDropShadow = TRUE; #else //webster has no page shadow. *ShowDropShadow = FALSE; #endif //webster // The dialog handler should have already set up the class variables pDocument and pSpread. // We will check that they are not null. // For now, get details on 1st page of spread 1 ERROR2IF(pDocument == NULL,FALSE,"PageTab::GetSizeOfPage no selected document"); ERROR2IF(pSpread == NULL,FALSE,"PageTab::GetSizeOfPage no spread to work on"); // Set up some interim variables MILLIPOINT PageWidth = *Width; MILLIPOINT PageHeight = *Height; MILLIPOINT PageMargin = *Margin; MILLIPOINT PageBleed = *Bleed; BOOL Pages = *Dps; BOOL DropShadow = *ShowDropShadow; if (pSpread != NULL) { BOOL ok = pSpread->GetPageSize(&PageWidth, &PageHeight, &PageMargin, &PageBleed, &Pages, &DropShadow); if (ok) { // page values read ok so set return parameters *Width = PageWidth; *Height = PageHeight; *Margin = PageMargin; *Bleed = PageBleed; *Dps = Pages; *ShowDropShadow = DropShadow; } else return FALSE; } // Now check if landscape or portrait if (PageWidth < PageHeight) { *Portrait = TRUE; *Width = PageWidth; *Height = PageHeight; } else { *Portrait = FALSE; *Width = PageHeight; *Height = PageWidth; } // Remember the states found OldPageWidth = PageWidth; // entry page width OldPageHeight = PageHeight; // entry page height OldDpsState = Pages; // entry state of dps OldDropShadowState = DropShadow; // entry drop shadow state OldMarginSize = PageMargin; // entry page margin size OldBleedSize = PageBleed; // entry page bleed size OldPortraitState = *Portrait; // entry portrait/landscape state return TRUE; } /****************************************************************************************** > BOOL PageTab::SetNewSizeOfPage(MILLIPOINT Width, MILLIPOINT Height, MILLIPOINT Margin, MILLIPOINT Bleed, BOOL Portrait, BOOL Dps, BOOL ShowDropShadow) Author: Neville_Humphrys (Xara Group Ltd) Created: 9/12/94 Inputs: Width new page width in millipoints Height new page height in millipoints Margin new page margin in millipoints Bleed new page bleed in millipoints Portrait set to TRUE if want Width smaller than height Dps set to TRUE if double page spread required Returns: True if found the details ok. Purpose: Checks to see what the size of the first page in the first spread in the document is and returns the width and height of it. Assumes at present a fairly simple document structure. This function should not no be used, should be using the undoable operation instead. Assumes the class variables pDocument, pSpread have been set up. Errors: - SeeAlso: AppPrefsDlg::SetCurrentSpread; InvokeResize; ******************************************************************************************/ //BOOL PageTab::SetNewSizeOfPage(MILLIPOINT Width, MILLIPOINT Height, MILLIPOINT Margin, // MILLIPOINT Bleed, BOOL Portrait, BOOL Dps, BOOL ShowDropShadow) //{ // BOOL ok = FALSE; // // // The dialog handler should have already set up the class variables pDocument and pSpread. // // We will check that they are not null. // // For now, get details on 1st page of spread 1 // ERROR2IF(pDocument == NULL,FALSE,"PageTab::SetNewSizeOfPage no selected document") // ERROR2IF(pSpread == NULL,FALSE,"PageTab::SetNewSizeOfPage no spread to work on") // // // Only change the page size/layout if something has changed // // If the user has changed anything then warn them that nothing will happen // MILLIPOINT bodge = 5; // extra leeway on comparison required // if ( (OldPageWidth <= (Width - bodge)) || (OldPageWidth >= (Width + bodge)) || // (OldPageHeight <= (Height - bodge)) || (OldPageHeight >= (Height + bodge)) || // OldDpsState != Dps || // OldPortraitState != Portrait || // OldDropShadowState != ShowDropShadow || // OldMarginSize != Margin || // OldBleedSize != Bleed) // { // // Changes made so resize all pages in the spread. // pSpread->SetPageSize(Width, Height, Margin, Bleed, Dps, ShowDropShadow); // // // Force all views onto the document to be updated // pDocument->ForceRedraw(); // // // And make these the new defaults // OldPageWidth = Width; // OldPageHeight = Height; // OldDpsState = Dps; // OldPortraitState = Portrait; // OldDropShadowState = ShowDropShadow; // OldMarginSize = Margin; // OldBleedSize = Bleed; // } // // return TRUE; //} /****************************************************************************************** > BOOL PageTab::InvokeResize(PageResizeInfo *Param) Author: Neville_Humphrys (Xara Group Ltd) Created: 17/2/95 Inputs: Returns: True if managed to change the page/spread details ok. Purpose: Sets the new details of the page size and of the default grid. The default grid should always be resident in the spread. Assumes the class variables pDocument, pSpread have been set up. This function should be used instead of SetNewSizeOfPage as it is undoable and they aren't. Errors: - SeeAlso: AppPrefsDlg::SetCurrentSpread; SetNewSizeOfPage; ******************************************************************************************/ BOOL PageTab::InvokeResize(PageResizeInfo *pParam) { ERROR2IF(pParam==NULL,FALSE,"PageTab::InvokeResize() no pParam supplied"); // For now, get details on 1st page of spread 1 // The dialog handler should have already set up the class variables pDocument and pSpread. // We will check that they are not null. ERROR2IF(pDocument==NULL,FALSE,"PageTab::InvokeResize() no selected document"); ERROR2IF( pSpread==NULL,FALSE,"PageTab::InvokeResize() no spread to work on"); // Only change the page size/layout if something has changed // If the user has changed anything then warn them that nothing will happen MILLIPOINT bodge = 5; // extra leeway on comparison required BOOL ChangeRequired = FALSE; if ( (OldPageWidth >= (pParam->Width - bodge)) && (OldPageWidth <= (pParam->Width + bodge)) && (OldPageHeight >= (pParam->Height - bodge)) && (OldPageHeight <= (pParam->Height + bodge)) && OldDpsState == pParam->Dps && OldDropShadowState == pParam->ShowDropShadow && (OldMarginSize >= (pParam->Margin - bodge)) && (OldMarginSize <= (pParam->Margin + bodge)) && (OldBleedSize >= (pParam->Bleed - bodge)) && (OldBleedSize <= (pParam->Bleed + bodge))) { // Set the page parameters so that we do not resize pParam->Height = 0; pParam->Width = 0; pParam->Margin = 0; pParam->Bleed = 0; pParam->Dps = FALSE; } else { // Flag we need to make a change ChangeRequired = TRUE; // Make these the new defaults OldPageWidth = pParam->Width; OldPageHeight = pParam->Height; OldDpsState = pParam->Dps; OldPortraitState = pParam->Portrait; OldDropShadowState = pParam->ShowDropShadow; OldMarginSize = pParam->Margin; OldBleedSize = pParam->Bleed; } if (ChangeRequired) { // Set the flag to say that we are doing a move and resize operation // rather than a centre and resize used by batching pParam->ResizeAndCentre = FALSE; // Invoke the Page resizing operation so that we get Undo. OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpPageResize)); if (pOpDesc != NULL) { // Set up the parameters which we require to do the page resizing operation pParam->pSpread = pSpread; // Go for it! pOpDesc->Invoke((OpParam *) pParam); } } return TRUE; } /****************************************************************************************** > BOOL PageTab::InvokeResizeAndCentre(PageResizeInfo *Param) Author: Neville_Humphrys (Xara Group Ltd) Created: 8/7/95 Inputs: Returns: True if managed to change the page/spread details ok. Purpose: Sets the new details of the page size and of the default grid. The default grid should always be resident in the spread. Assumes the class variables pDocument, pSpread have been set up. This function should be used instead of SetNewSizeOfPage as it is undoable and they aren't. This does the same as resize but centres the objects on the page. Used by the batching code. Errors: - SeeAlso: AppPrefsDlg::SetCurrentSpread; SetNewSizeOfPage; ******************************************************************************************/ BOOL PageTab::InvokeResizeAndCentre(PageResizeInfo *pParam) { ERROR2IF(pParam==NULL,FALSE,"PageTab::InvokeResizeAndCentre() no pParam supplied"); // The dialog handler should have already set up the class variables pDocument and pSpread. // We will check that they are not null. ERROR2IF(pDocument==NULL,FALSE,"PageTab::InvokeResizeAndCentre() no selected document"); ERROR2IF( pSpread==NULL,FALSE,"PageTab::InvokeResizeAndCentre() no spread to work on"); // Flag we need to make a change // BOOL ChangeRequired = TRUE; // Make these the new defaults OldPageWidth = pParam->Width; OldPageHeight = pParam->Height; OldDpsState = pParam->Dps; OldPortraitState = pParam->Portrait; OldDropShadowState = pParam->ShowDropShadow; OldMarginSize = pParam->Margin; OldBleedSize = pParam->Bleed; // Set the flag to say that we are doing a centre and resize operation pParam->ResizeAndCentre = TRUE; // Invoke the Page resizing operation so that we get Undo. OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpPageResize)); if (pOpDesc != NULL) { // Set up the parameters which we require to do the page resizing operation pParam->pSpread = pSpread; // Go for it! pOpDesc->Invoke((OpParam *) pParam); } return TRUE; } ////////////////////////// OpPageResize class ... ///////////////////////////////////////// /****************************************************************************************** > OpPageResize::OpPageResize() : UndoableOperation() Author: Neville_Humphrys (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: - Purpose: OpPageResize constructor (Creates an undoable operation) SeeAlso: PageTab; ******************************************************************************************/ OpPageResize::OpPageResize() : TransOperation() //UndoableOperation() { } /******************************************************************************************** > OpPageResize::~OpPageResize() Author: Neville_Humphrys (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: - Purpose: OpPageResize destructor Errors: - SeeAlso: - ********************************************************************************************/ OpPageResize::~OpPageResize() { } /****************************************************************************************** > BOOL OpAlign::Init() Author: Neville_Humphrys (Xara Group Ltd) Created: 13/2/95 Returns: FALSE if it fails (due to lack of memory) Purpose: Creates an OpDescriptor for a Page Resize operation SeeAlso: PageTab; ******************************************************************************************/ BOOL OpPageResize::Init() { return RegisterOpDescriptor( 0, // Tool ID _R(IDS_OPPAGERESIZE), // String resource ID CC_RUNTIME_CLASS(OpPageResize), // Runtime class OPTOKEN_OPPAGERESIZE, // Token string OpPageResize::GetState, // GetState function 0, // Help ID 0, // Bubble ID 0, // Resource ID 0 // Control ID // needs 'GREY_WHEN_NO_CURRENT_DOC' ); } /****************************************************************************************** > OpState OpPageResize::GetState(String_256* pString, OpDescriptor* pOpDesc) Author: Neville_Humphrys (Xara Group Ltd) Created: 13/2/95 Purpose: Returns the OpState of the OpPageResize dialogue operation. SeeAlso: PageTab; ******************************************************************************************/ OpState OpPageResize::GetState(String_256* pString, OpDescriptor* pOpDesc) { OpState OpSt; return(OpSt); } /******************************************************************************************** > void OpPageResize::Do(OpDescriptor*) Author: Neville_Humphrys (Xara Group Ltd) Created: 13/2/95 Inputs: OpPageResize (unused) Outputs: - Returns: - Purpose: (Performs the page resizing operation) OpPageResize has a special overloaded Do operator which takes parameters describing what is to be done - that version of Do must be used Errors: Always generates an ENSURE failure because this Do doesn't. SeeAlso: - ********************************************************************************************/ void OpPageResize::Do(OpDescriptor *NotUsed) { ENSURE(FALSE, "OpPageResize does not provide a Do() function - Use DoWithParam"); End(); } /****************************************************************************************** > void OpPageResize::DoWithParam(OpDescriptor* pOp, OpParam* pAlignParam) Author: Neville_Humphrys (Xara Group Ltd) Created: 13/2/95 Inputs: pOp - OpDescriptor as for all Do() functions Param - points to a Page resize structure with parameters: pSpread - The spread to be changed Outputs: - Returns: - Purpose: Performs the page/spread resize operation, which resizes the pages in the specified spread (with undo) to the new size. Forces a redraw of the parent document for the specified spread. SeeAlso: PageTab::SetNewSizeOfPage; ******************************************************************************************/ void OpPageResize::DoWithParam(OpDescriptor* pOp, OpParam* pResizeParam) { PageResizeInfo *pInfo = (PageResizeInfo *) pResizeParam; ERROR3IF(pInfo == NULL,"OpPageResize called with NULL info pointer"); ERROR3IF((pInfo == NULL) && (pInfo->pSpread == NULL),"OpPageResize called with NULL spread pointer"); // Fail if the input parameters are incorrect if ((pInfo == NULL) || (pInfo->pSpread == NULL)) { FailAndExecute(); End(); return; } Spread * pTheSpread = pInfo->pSpread; // As we are derived off TransOperation then we MUST call DoStartTransOp otherwise // it seems to fall over in a very nasty way! // Find the spreads first layer Layer* pCurrentLayer = pTheSpread->FindFirstLayer(); ERROR3IF(pCurrentLayer == NULL,"OpPageResize specified spread has no layers"); // Fail if the input parameters are incorrect if (pCurrentLayer == NULL) { FailAndExecute(); End(); return; } // Find all objects on this spread, selected or unselected and move them. // Range Control parameters are:- // Include selected nodes - we want TRUE. // Include Unselected nodes - we want TRUE. // Cross layers - we want TRUE // Ignore locked layers - we want FALSE so that we include locked layers. // IsRenderable if set then calls NeedsToRender - we want TRUE // Ignore invisible layers - we want TRUE so that we include invisible layers. // DMc - included the promote to parents flag Range SearchRange(pCurrentLayer, NULL, RangeControl(TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE)); // Must call this so that the Translation operation is set up ok. // NOTE! A FALSE return may simply mean there are no objects on the page! BOOL StartTransOpOk = DoStartTransOp(FALSE, NULL, &SearchRange); // See if we must do some resizing of the page(s). // If no change is required then both the height and width passed in will be zero if ((pInfo->Width != 0) && (pInfo->Height != 0)) { // Get the details on the present page layout so that we can use this to undo what we // are about to try and do MILLIPOINT PageWidth = 0; MILLIPOINT PageHeight = 0; MILLIPOINT PageMargin = 0; MILLIPOINT PageBleed = 0; BOOL PresentDps = 0; BOOL PresentDropShadow = 0; pTheSpread->GetPageSize(&PageWidth, &PageHeight, &PageMargin, &PageBleed, &PresentDps, &PresentDropShadow); // Create an action to Undo the resizing operation ActionPageResize *APR; ActionCode PageResizeAction = ActionPageResize::Init( this, &UndoActions, sizeof(ActionPageResize), pInfo->pSpread, PageWidth, PageHeight, PageMargin, PageBleed, PresentDps, PresentDropShadow, (Action**)(&APR) ); // If the init happened ok then go and do the first operation if (PageResizeAction != AC_FAIL) { // If the DoStartTransOp happened ok then move the objects on the page if (StartTransOpOk) { // Reposition the objects on the page correctly. // Do this first as if going from large to small the old position of the objects // might limit the size of the paste rectangle whereas the new positions wont. if ( !MoveObjectsOnPage(pTheSpread, pInfo->Width, pInfo->Height, pInfo->Margin, pInfo->Dps, PageWidth, PageHeight, PageMargin, PresentDps, &SearchRange, pInfo->ResizeAndCentre ) ) { FailAndExecute(); End(); return; } } // Apply the initial 'Do' operation - resize that page // Save away the current spreads pasteboard rectangle as the specified margin // may be overridden if the bounding rectangle of the objects on the page would // not fit into a rectangle encompassing the new page structure and having a // margin gap around all 4 sides. PasteboardRect = pTheSpread->GetPasteboardRect(); pTheSpread->SetPageSize(pInfo->Width, pInfo->Height, pInfo->Margin, pInfo->Bleed, pInfo->Dps, pInfo->ShowDropShadow); } else { FailAndExecute(); End(); return; } } // NodeGrid* pGrid = NULL; // // pGrid = pTheSpread->FindFirstDefaultGridInSpread(); // ERROR3IF(pGrid == NULL,"ActionSetDefaultGrid::Execute() no current default grid") // // // Must set the origin of the grid to the bottom left corner of the // // union rectangle of all pages on the spread as this is where the x,y // // measurements are made from. // DocRect PagesRect; // BOOL ok = pTheSpread->GetPagesRect(&PagesRect); // if (ok) // { // pGrid->SetOrigin(PagesRect.lo.x,PagesRect.lo.y); //TRACEUSER( "Neville", _T("OpPageResize Grid origin at %d, %d\n"),PagesRect.lo.x,PagesRect.lo.y); // } // We must have been called to change either the page size OR the grid so always // force a redraw // If everything has gone swimmingly then last thing is to redraw the document // JustinF says: only do this if the document isn't hidden, ie. it's one of the user's. // Don't do this if it's a hidden doc, such as the clipboard. Document *pParentDoc = (Document *)pTheSpread->FindOwnerDoc(); if (pParentDoc != NULL && !pParentDoc->IsAHiddenDoc()) { // Broadcast the special NEWPAGESIZE message which does not try and update the // page tab. pParentDoc->ForceRedraw(); BROADCAST_TO_ALL(OptionsChangingMsg(pParentDoc, OptionsChangingMsg::PAGESIZEHASCHANGED)); } // If we reached here then everything has happened ok and we can just end the // operation and exit End(); return; } /****************************************************************************************** > BOOL OpPageResize::MoveObjectsOnPage(Spread *pSpread, MILLIPOINT Width, MILLIPOINT Height, MILLIPOINT Margin, BOOL Dps, MILLIPOINT OldWidth, MILLIPOINT OldHeight, MILLIPOINT OldMargin, BOOL OldDps, Range *pSearchRange, BOOL ResizeAndCentre) Author: Neville_Humphrys (Xara Group Ltd) Created: 20/4/95 Inputs: pSpread - pointer to the spread whose objects areto be moved Width - new page width Height - new page height Margin - new page margin Dps - single (FALSE) or double (TRUE) page spread flag Width - old page width Height - old page height Margin - old page margin Dps - old single (FALSE) or double (TRUE) page spread flag pSearchRange- the range to be trasnformed ResizeAndCentre - Set True if want a centre and resize operation - False if want the resize and move operation Outputs: - Returns: - Purpose: As part of the page/spread resize operation, which resizes the pages in the specified spread (with undo) to the new size, we must translate the objects on the page to a better position. SeeAlso: OpPageResize::DoWithParam; ActionPageResize; PageTab::SetNewSizeOfPage; ******************************************************************************************/ BOOL OpPageResize::MoveObjectsOnPage(Spread *pSpread, MILLIPOINT Width, MILLIPOINT Height, MILLIPOINT Margin, BOOL Dps, MILLIPOINT OldWidth, MILLIPOINT OldHeight, MILLIPOINT OldMargin, BOOL OldDps, Range *pSearchRange, BOOL ResizeAndCentre) { ERROR2IF(pSpread == NULL, FALSE,"OpPageResize::MoveObjectsOnPage specified spread is null"); ERROR2IF(pSearchRange == NULL, FALSE,"OpPageResize::MoveObjectsOnPage specified range is null"); // Found no nodes on the page according to this spec so nothing to move if (pSearchRange->FindFirst() == NULL) return TRUE; // Work out the rectangle encompassing the old page structure MILLIPOINT OldWidthOfPages = 0; if (OldDps) OldWidthOfPages = OldMargin + 2 * OldWidth; else OldWidthOfPages = OldWidth; DocRect OldPagesRect(OldMargin, OldMargin, OldMargin + OldWidthOfPages + OldMargin, OldMargin + OldHeight + OldMargin); // Work out the rectangle encompassing the new page structure MILLIPOINT WidthOfPages = 0; if (Dps) WidthOfPages = Margin + 2 * Width; else WidthOfPages = Width; DocRect NewPagesRect(Margin, Margin, Margin + WidthOfPages + Margin, Margin + Height + Margin); MILLIPOINT dx = 0; MILLIPOINT dy = 0; if (ResizeAndCentre) { /* Centre items on page... */ DocRect OurItemRect(pSearchRange->GetBoundingRect()); DocCoord ItemCentre((OurItemRect.Width()/2) + OurItemRect.lo.x, (OurItemRect.Height()/2) + OurItemRect.lo.y); DocCoord PageCentre(Width / 2, Height / 2); dx = PageCentre.x - ItemCentre.x; dy = PageCentre.y - ItemCentre.y; dx += Margin; dy += Margin; } else { // Work out the difference between the centre points of the page structures // MILLIPOINT dx = NewPagesRect.lo.x + NewPagesRect.Width()/2 // - (OldPagesRect.lo.x + OldPagesRect.Width()/2); // MILLIPOINT dy = NewPagesRect.lo.y + NewPagesRect.Height()/2 // - (OldPagesRect.lo.y + OldPagesRect.Height()/2); dx = NewPagesRect.lo.x - OldPagesRect.lo.x; dy = NewPagesRect.lo.y - OldPagesRect.lo.y; TRACEUSER( "Neville", _T("Old spread low x,y %d, %d\n"), OldPagesRect.lo.x, OldPagesRect.lo.y); TRACEUSER( "Neville", _T("New spread low x,y %d, %d\n"), NewPagesRect.lo.x, NewPagesRect.lo.y); TRACEUSER( "Neville", _T("Distance to move is %d, %d\n"), dx, dy); } // If the movement required is small then forget it const MILLIPOINT bodge = 100; if ( (dx >= -bodge) && (dx <= bodge) && (dy >= -bodge) && (dy <= bodge) ) return TRUE; // Construct the translation matrix that we want to apply to the objects Trans2DMatrix* pMatrix = new Trans2DMatrix(dx, dy); // Move all those nodes by the required amount (if it is a Renderable Ink Node) DoTransformNodes(*pSearchRange, pMatrix); // Update the selection cache GetApplication()->UpdateSelection(); return TRUE; } /******************************************************************************************** > ActionPageResize::ActionPageResize() Author: Neville_Humphrys (Xara Group Ltd) Created: 15/2/95 Purpose: ActionPageResize constructor ********************************************************************************************/ ActionPageResize::ActionPageResize() { } /******************************************************************************************** > ActionPageResize::~ActionPageResize() Author: Neville_Humphrys (Xara Group Ltd) Created: 15/2/95 Purpose: ActionPageResize destructor ********************************************************************************************/ ActionPageResize::~ActionPageResize() { } /******************************************************************************************** > virtual ActionCode ActionPageResize::Execute() Author: Neville_Humphrys (Xara Group Ltd) Created: 15/2/95 Inputs: - Outputs: ActionCode indicating if the action was successfully executed or not Returns: - Purpose: Executes the ActionPageResize to go and resize the current spread/page and generates another ActionPageResize to undo this change. Forces a redraw of the parent document for the specified spread. ********************************************************************************************/ ActionCode ActionPageResize::Execute() { ActionPageResize PageResizeAct; ActionCode ActCode = AC_FAIL; // Get the details on the present page layout so that we can use this to undo what we // are about to try and do MILLIPOINT PageWidth = 0; MILLIPOINT PageHeight = 0; MILLIPOINT PageMargin = 0; MILLIPOINT PageBleed = 0; BOOL PresentDps = 0; BOOL PresentDropShadow = 0; if (pSpread != NULL) { pSpread->GetPageSize(&PageWidth, &PageHeight, &PageMargin, &PageBleed, &PresentDps, &PresentDropShadow); } // Create an action to restore the changes we are about to make if ((ActCode = ActionPageResize::Init(pOperation, pOppositeActLst, sizeof(ActionPageResize), pSpread, PageWidth, PageHeight, PageMargin, PageBleed, PresentDps, PresentDropShadow, ( Action**)(&PageResizeAct))) != AC_FAIL) { // Need to do something here if (pSpread != NULL) { // Save away the current spreads pasteboard rectangle as the specified margin // may be overridden if the bounding rectangle of the objects on the page would // not fit into a rectangle encompassing the new page structure and having a // margin gap around all 4 sides. PasteboardRect = pSpread->GetPasteboardRect(); pSpread->SetPageSize(Width, Height, Margin, Bleed, Dps, ShowDropShadow); // Force all views onto the document to be updated Document *pParentDoc = (Document *)pSpread->FindOwnerDoc(); if (pParentDoc != NULL) { pParentDoc->ForceRedraw(); BROADCAST_TO_ALL(OptionsChangingMsg( pParentDoc, OptionsChangingMsg::NEWPAGESIZE ) ); } } } return (ActCode); } /******************************************************************************************** > ActionCode ActionPageResize::Init(Operation* const pOp, ActionList* pActionList, UINT32 ActionSize, Spread *pSpread, Page *pPage, Action** NewAction) Author: Neville_Humphrys (Xara Group Ltd) Created: 15/2/95 Inputs: pOp: The operation to which the action should be added pActionList: The action list in the operation object ActionSize: The size of the action in bytes. This should be the total size of the action (including any objects pointed to by the action). pSpread: The target spread which will be changed when we are executed Height The new page height required. Width The new page width required. Margin The new page margin required. Bleed The new page bleed required. Dps The new single/double page spread required. ShowPageShadow The new page shadow display state required. Outputs: NewAction: A pointer to the action if it could be allocated. Returns: AC_FAIL: There was not enough room in the operation history for the action and the user did not wish to continue. Usually End() should be called in this situation. AC_NORECORD: There was not enough room in the operation history for the action, but the user requested that he wished to continue without undo. AC_OK : The action was successfully initialised and added to the operation. Purpose: To check that there is sufficient room for the action in the operation history, and if there is, then to add the action to the operations action list. The function calls the Action::Init function passing the runtime class of an ActionPageResize. Errors: - SeeAlso: Action::Init; OpPageResize; PageTab::SetNewSizeOfPage; ********************************************************************************************/ ActionCode ActionPageResize::Init(Operation* const pOp, ActionList* pActionList, UINT32 ActionSize, Spread *pTheSpread, MILLIPOINT NewWidth, MILLIPOINT NewHeight, MILLIPOINT NewMargin, MILLIPOINT NewBleed, BOOL NewDps, BOOL NewShowDropShadow, Action** NewAction) { ActionCode Ac = (Action::Init(pOp, pActionList, ActionSize, CC_RUNTIME_CLASS(ActionPageResize), NewAction)); if (*NewAction != NULL) { ActionPageResize *ACC = (ActionPageResize*) (*NewAction); ACC->pSpread = pTheSpread; ACC->Width = NewWidth; ACC->Height = NewHeight; ACC->Margin = NewMargin; ACC->Bleed = NewBleed; ACC->Dps = NewDps; ACC->ShowDropShadow = NewShowDropShadow; } return (Ac); }