# # This file is part of the LibreOffice project. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # This file incorporates work covered by the following license notice: # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed # with this work for additional information regarding copyright # ownership. The ASF licenses this file to you under the Apache # License, Version 2.0 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of # the License at http://www.apache.org/licenses/LICENSE-2.0 . # import uno import traceback from abc import ABCMeta, abstractmethod from .UnoDialog2 import UnoDialog2, Desktop, PropertyNames, UIConsts, \ ItemListenerProcAdapter from ..common.HelpIds import HelpIds from ..common.FileAccess import FileAccess from com.sun.star.lang import NoSuchMethodException from com.sun.star.frame import TerminationVetoException from com.sun.star.awt.PushButtonType import HELP, STANDARD from com.sun.star.awt.FontWeight import BOLD import sys, os if sys.version_info < (3,4): import imp imp.load_source('strings', os.path.join(os.path.dirname(__file__), '../common/strings.hrc')) import strings elif sys.version_info < (3,7): # imp is deprecated since Python v.3.4 from importlib.machinery import SourceFileLoader SourceFileLoader('strings', os.path.join(os.path.dirname(__file__), '../common/strings.hrc')).load_module() import strings else: # have to jump through hoops since 3.7, partly because python does not like loading modules that do have a .py extension import importlib import importlib.util import importlib.machinery module_name = 'strings' path = os.path.join(os.path.dirname(__file__), '../common/strings.hrc') spec = importlib.util.spec_from_loader( module_name, importlib.machinery.SourceFileLoader(module_name, path) ) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) sys.modules[module_name] = module strings = module class WizardDialog(UnoDialog2): __metaclass__ = ABCMeta __NEXT_ACTION_PERFORMED = "gotoNextAvailableStep" __BACK_ACTION_PERFORMED = "gotoPreviousAvailableStep" __FINISH_ACTION_PERFORMED = "finishWizard_1" __CANCEL_ACTION_PERFORMED = "cancelWizard_1" __HELP_ACTION_PERFORMED = None ''' Creates a new instance of WizardDialog the hid is used as following : "HID:(hid)" - the dialog "HID:(hid+1) - the help button "HID:(hid+2)" - the back button "HID:(hid+3)" - the next button "HID:(hid+4)" - the create button "HID:(hid+5)" - the cancel button @param xMSF @param hid_ ''' def __init__(self, xMSF, hid_): super(WizardDialog,self).__init__(xMSF) self.__hid = hid_ self.iButtonWidth = 50 self.nNewStep = 1 self.nOldStep = 1 self.nMaxStep = 1 self.bTerminateListenermustberemoved = True self.oRoadmap = None self.terminateListener = None def activate(self): try: self.xUnoDialog.toFront() except Exception: pass # do nothing; def itemStateChanged(self, itemEvent): try: self.nNewStep = itemEvent.ItemId self.nOldStep = int(self.xDialogModel.Step) if self.nNewStep != self.nOldStep: self.switchToStep() except Exception: traceback.print_exc() def setDialogProperties(self, closeable, height, moveable, position_x, position_Y, step, tabIndex, title, width): uno.invoke(self.xDialogModel, "setPropertyValues", ((PropertyNames.PROPERTY_CLOSEABLE, PropertyNames.PROPERTY_HEIGHT, PropertyNames.PROPERTY_MOVEABLE, PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y, PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_TABINDEX, PropertyNames.PROPERTY_TITLE, PropertyNames.PROPERTY_WIDTH), (closeable, height, moveable, position_x, position_Y, step, tabIndex, title, width))) def setRoadmapInteractive(self, _bInteractive): self.oRoadmap.Activated = _bInteractive def setRoadmapComplete(self, bComplete): self.oRoadmap.Complete = bComplete def isRoadmapComplete(self): try: return bool(self.oRoadmap.Complete) except Exception: traceback.print_exc() return False def setCurrentRoadmapItemID(self, ID): if self.oRoadmap is not None: nCurItemID = self.getCurrentRoadmapItemID() if nCurItemID != ID: self.oRoadmap.CurrentItemID = ID def getCurrentRoadmapItemID(self): try: return int(self.oRoadmap.CurrentItemID) except Exception: traceback.print_exc() return -1 def initializePaths(self): xPropertySet = \ self.xMSF.createInstance("com.sun.star.util.PathSettings") self.sUserTemplatePath = \ xPropertySet.getPropertyValue("Template_writable") myFA = FileAccess(self.xMSF) aInternalPaths = xPropertySet.getPropertyValue("Template_internal") self.sTemplatePath = "" for path in aInternalPaths: if myFA.exists(path + "/wizard", False): self.sTemplatePath = path break if self.sTemplatePath == "": raise Exception("could not find wizard templates") def addRoadmap(self): try: iDialogHeight = self.xDialogModel.Height # the roadmap control has got no real TabIndex ever # that is not correct, but changing this would need time, # so it is used without TabIndex as before xRoadmapControl = self.insertControlModel( "com.sun.star.awt.UnoControlRoadmapModel", "rdmNavi", (PropertyNames.PROPERTY_HEIGHT, PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y, PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_TABINDEX, "Tabstop", PropertyNames.PROPERTY_WIDTH), ((iDialogHeight - 26), 0, 0, 0, 0, True, 85)) self.oRoadmap = xRoadmapControl.Model method = getattr(self, "itemStateChanged") xRoadmapControl.addItemListener( ItemListenerProcAdapter(method)) self.oRoadmap.Text = strings.RID_COMMON_START_16 except NoSuchMethodException: from com.sun.star.awt.VclWindowPeerAttribute import OK from .SystemDialog import SystemDialog sError = "The files required could not be found.\n" + \ "Please start the LibreOffice Setup and choose 'Repair'." SystemDialog.showMessageBox(super().xMSF, "ErrorBox", OK, sError) except Exception: traceback.print_exc() def getRoadmapItemByID(self, _ID): try: getByIndex = self.oRoadmap.getByIndex for i in list(range(self.oRoadmap.Count)): CurRoadmapItem = getByIndex(i) CurID = int(CurRoadmapItem.ID) if CurID == _ID: return CurRoadmapItem return None except Exception: traceback.print_exc() return None def switchToStep(self,_nOldStep=None, _nNewStep=None): if _nOldStep is not None and _nNewStep is not None: self.nOldStep = _nOldStep self.nNewStep = _nNewStep self.leaveStep(self.nOldStep, self.nNewStep) if self.nNewStep != self.nOldStep: if self.nNewStep == self.nMaxStep: self.xDialogModel.btnWizardNext.DefaultButton = False self.xDialogModel.btnWizardFinish.DefaultButton = True else: self.xDialogModel.btnWizardNext.DefaultButton = True self.xDialogModel.btnWizardFinish.DefaultButton = False self.changeToStep(self.nNewStep) self.enterStep(self.nOldStep, self.nNewStep) return True return False @abstractmethod def leaveStep(self, nOldStep, nNewStep): pass @abstractmethod def enterStep(self, nOldStep, nNewStep): pass def changeToStep(self, nNewStep): self.xDialogModel.Step = nNewStep self.setCurrentRoadmapItemID(nNewStep) self.enableNextButton(self.getNextAvailableStep() > 0) self.enableBackButton(nNewStep != 1) def drawNaviBar(self): try: curtabindex = UIConsts.SOFIRSTWIZARDNAVITABINDEX iButtonWidth = self.iButtonWidth iButtonHeight = 14 iCurStep = 0 iDialogHeight = self.xDialogModel.Height iDialogWidth = self.xDialogModel.Width iHelpPosX = 8 iBtnPosY = iDialogHeight - iButtonHeight - 6 iCancelPosX = iDialogWidth - self.iButtonWidth - 6 iFinishPosX = iCancelPosX - 6 - self.iButtonWidth iNextPosX = iFinishPosX - 6 - self.iButtonWidth iBackPosX = iNextPosX - 3 - self.iButtonWidth self.insertControlModel( "com.sun.star.awt.UnoControlFixedLineModel", "lnNaviSep", (PropertyNames.PROPERTY_HEIGHT, "Orientation", PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y, PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_WIDTH), (1, 0, 0, iDialogHeight - 26, iCurStep, iDialogWidth)) self.insertControlModel( "com.sun.star.awt.UnoControlFixedLineModel", "lnRoadSep", (PropertyNames.PROPERTY_HEIGHT, "Orientation", PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y, PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_WIDTH), (iBtnPosY - 6, 1, 85, 0, iCurStep, 1)) propNames = (PropertyNames.PROPERTY_ENABLED, PropertyNames.PROPERTY_HEIGHT, PropertyNames.PROPERTY_HELPURL, PropertyNames.PROPERTY_LABEL, PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y, "PushButtonType", PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_TABINDEX, PropertyNames.PROPERTY_WIDTH) self.xDialogModel.HelpURL = HelpIds.getHelpIdString(self.__hid) self.insertButton("btnWizardHelp", WizardDialog.__HELP_ACTION_PERFORMED, (PropertyNames.PROPERTY_ENABLED, PropertyNames.PROPERTY_HEIGHT, PropertyNames.PROPERTY_LABEL, PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y, "PushButtonType", PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_TABINDEX, PropertyNames.PROPERTY_WIDTH), (True, iButtonHeight, strings.RID_COMMON_START_15, iHelpPosX, iBtnPosY, uno.Any("short",HELP), iCurStep, uno.Any("short",(curtabindex + 1)), iButtonWidth), self) self.insertButton("btnWizardBack", WizardDialog.__BACK_ACTION_PERFORMED, propNames, (False, iButtonHeight, HelpIds.getHelpIdString(self.__hid + 2), strings.RID_COMMON_START_13, iBackPosX, iBtnPosY, uno.Any("short",STANDARD), iCurStep, uno.Any("short",(curtabindex + 1)), iButtonWidth), self) self.insertButton("btnWizardNext", WizardDialog.__NEXT_ACTION_PERFORMED, propNames, (True, iButtonHeight, HelpIds.getHelpIdString(self.__hid + 3), strings.RID_COMMON_START_14, iNextPosX, iBtnPosY, uno.Any("short",STANDARD), iCurStep, uno.Any("short",(curtabindex + 1)), iButtonWidth), self) self.insertButton("btnWizardFinish", WizardDialog.__FINISH_ACTION_PERFORMED, propNames, (True, iButtonHeight, HelpIds.getHelpIdString(self.__hid + 4), strings.RID_COMMON_START_12, iFinishPosX, iBtnPosY, uno.Any("short",STANDARD), iCurStep, uno.Any("short",(curtabindex + 1)), iButtonWidth), self) self.insertButton("btnWizardCancel", WizardDialog.__CANCEL_ACTION_PERFORMED, propNames, (True, iButtonHeight, HelpIds.getHelpIdString(self.__hid + 5), strings.RID_COMMON_START_11, iCancelPosX, iBtnPosY, uno.Any("short",STANDARD), iCurStep, uno.Any("short",(curtabindex + 1)), iButtonWidth), self) self.xDialogModel.btnWizardNext.DefaultButton = True except Exception: traceback.print_exc() def insertRoadMapItems(self, items, enabled): for index, item in enumerate(items): try: oRoadmapItem = self.oRoadmap.createInstance() oRoadmapItem.Label = item oRoadmapItem.Enabled = enabled[index] oRoadmapItem.ID = index + 1 self.oRoadmap.insertByIndex(index, oRoadmapItem) except Exception: traceback.print_exc() def enableBackButton(self, enabled): self.xDialogModel.btnWizardBack.Enabled = enabled def enableNextButton(self, enabled): self.xDialogModel.btnWizardNext.Enabled = enabled def enableFinishButton(self, enabled): self.xDialogModel.btnWizardFinish.Enabled = enabled def isStepEnabled(self, _nStep): try: xRoadmapItem = self.getRoadmapItemByID(_nStep) # Todo: In this case an exception should be thrown if xRoadmapItem is None: return False bIsEnabled = bool(xRoadmapItem.Enabled) return bIsEnabled except Exception: traceback.print_exc() return False def gotoPreviousAvailableStep(self): try: if self.nNewStep > 1: self.nOldStep = self.nNewStep self.nNewStep -= 1 while self.nNewStep > 0: bIsEnabled = self.isStepEnabled(self.nNewStep) if bIsEnabled: break; self.nNewStep -= 1 if (self.nNewStep == 0): self.nNewStep = self.nOldStep self.switchToStep() except Exception: traceback.print_exc() def getNextAvailableStep(self): if self.isRoadmapComplete(): i = self.nNewStep + 1 while i <= self.nMaxStep: if self.isStepEnabled(i): return i i += 1 return -1 def gotoNextAvailableStep(self): try: self.nOldStep = self.nNewStep self.nNewStep = self.getNextAvailableStep() if self.nNewStep > -1: self.switchToStep() except Exception: traceback.print_exc() @abstractmethod def finishWizard(self): pass def finishWizard_1(self): '''This function will call if the finish button is pressed on the UI''' try: self.enableFinishButton(False) success = False try: success = self.finishWizard() finally: if not success: self.enableFinishButton(True) if success: self.removeTerminateListener() except Exception: traceback.print_exc() def getCurrentStep(self): try: return int(self.xDialogModel.Step) except Exception: traceback.print_exc() return -1 def cancelWizard(self): #can be overwritten by extending class self.xUnoDialog.endExecute() def removeTerminateListener(self): if self.bTerminateListenermustberemoved: Desktop.getDesktop(self.xMSF).removeTerminateListener(self.terminateListener) self.bTerminateListenermustberemoved = False ''' called by the cancel button and by the window hidden event. if this method was not called before, perform a cancel. ''' def cancelWizard_1(self): try: self.cancelWizard() self.removeTerminateListener() except Exception: traceback.print_exc() def windowHidden(self): self.cancelWizard_1() def queryTermination(self): self.activate() raise TerminationVetoException() def disposing(self, arg0): self.cancelWizard_1() def optCreateFromTemplateItemChanged(self): self.bEditTemplate = False def optMakeChangesItemChanged(self): self.bEditTemplate = True