codekingpro/portable-devtools
114k
1# Copyright (c) 2023, Pubpub-ZZ2#3# All rights reserved.4#5# Redistribution and use in source and binary forms, with or without6# modification, are permitted provided that the following conditions are7# met:8#9# * Redistributions of source code must retain the above copyright notice,10# this list of conditions and the following disclaimer.11# * Redistributions in binary form must reproduce the above copyright notice,12# this list of conditions and the following disclaimer in the documentation13# and/or other materials provided with the distribution.14# * The name of the author may not be used to endorse or promote products15# derived from this software without specific prior written permission.16#17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE27# POSSIBILITY OF SUCH DAMAGE.28 29from typing import (30 Any,31 Optional,32 cast,33)34 35from ._base import BooleanObject, NameObject, NumberObject, is_null_or_none36from ._data_structures import ArrayObject, DictionaryObject37 38f_obj = BooleanObject(False)39 40 41class ViewerPreferences(DictionaryObject):42 def __init__(self, obj: Optional[DictionaryObject] = None) -> None:43 super().__init__(self)44 if not is_null_or_none(obj):45 self.update(obj.items()) # type: ignore46 try:47 self.indirect_reference = obj.indirect_reference # type: ignore48 except AttributeError:49 pass50 51 def _get_bool(self, key: str, default: Optional[BooleanObject]) -> Optional[BooleanObject]:52 return self.get(key, default)53 54 def _set_bool(self, key: str, v: bool) -> None:55 self[NameObject(key)] = BooleanObject(v is True)56 57 def _get_name(self, key: str, default: Optional[NameObject]) -> Optional[NameObject]:58 return self.get(key, default)59 60 def _set_name(self, key: str, lst: list[str], v: NameObject) -> None:61 if v[0] != "/":62 raise ValueError(f"{v} does not start with '/'")63 if lst != [] and v not in lst:64 raise ValueError(f"{v} is an unacceptable value")65 self[NameObject(key)] = NameObject(v)66 67 def _get_arr(self, key: str, default: Optional[list[Any]]) -> Optional[ArrayObject]:68 return self.get(key, None if default is None else ArrayObject(default))69 70 def _set_arr(self, key: str, v: Optional[ArrayObject]) -> None:71 if v is None:72 try:73 del self[NameObject(key)]74 except KeyError:75 pass76 return77 if not isinstance(v, ArrayObject):78 raise ValueError("ArrayObject is expected")79 self[NameObject(key)] = v80 81 def _get_int(self, key: str, default: Optional[NumberObject]) -> Optional[NumberObject]:82 return self.get(key, default)83 84 def _set_int(self, key: str, v: int) -> None:85 self[NameObject(key)] = NumberObject(v)86 87 @property88 def PRINT_SCALING(self) -> NameObject:89 return NameObject("/PrintScaling")90 91 def __new__(cls: Any, value: Any = None) -> "ViewerPreferences": # noqa: PYI03492 def _add_prop_bool(key: str, default: Optional[BooleanObject]) -> property:93 return property(94 lambda self: self._get_bool(key, default),95 lambda self, v: self._set_bool(key, v),96 None,97 f"""98 Returns/Modify the status of {key}, Returns {default} if not defined99 """,100 )101 102 def _add_prop_name(103 key: str, lst: list[str], default: Optional[NameObject]104 ) -> property:105 return property(106 lambda self: self._get_name(key, default),107 lambda self, v: self._set_name(key, lst, v),108 None,109 f"""110 Returns/Modify the status of {key}, Returns {default} if not defined.111 Acceptable values: {lst}112 """,113 )114 115 def _add_prop_arr(key: str, default: Optional[ArrayObject]) -> property:116 return property(117 lambda self: self._get_arr(key, default),118 lambda self, v: self._set_arr(key, v),119 None,120 f"""121 Returns/Modify the status of {key}, Returns {default} if not defined122 """,123 )124 125 def _add_prop_int(key: str, default: Optional[int]) -> property:126 return property(127 lambda self: self._get_int(key, default),128 lambda self, v: self._set_int(key, v),129 None,130 f"""131 Returns/Modify the status of {key}, Returns {default} if not defined132 """,133 )134 135 cls.hide_toolbar = _add_prop_bool("/HideToolbar", f_obj)136 cls.hide_menubar = _add_prop_bool("/HideMenubar", f_obj)137 cls.hide_windowui = _add_prop_bool("/HideWindowUI", f_obj)138 cls.fit_window = _add_prop_bool("/FitWindow", f_obj)139 cls.center_window = _add_prop_bool("/CenterWindow", f_obj)140 cls.display_doctitle = _add_prop_bool("/DisplayDocTitle", f_obj)141 142 cls.non_fullscreen_pagemode = _add_prop_name(143 "/NonFullScreenPageMode",144 ["/UseNone", "/UseOutlines", "/UseThumbs", "/UseOC"],145 NameObject("/UseNone"),146 )147 cls.direction = _add_prop_name(148 "/Direction", ["/L2R", "/R2L"], NameObject("/L2R")149 )150 cls.view_area = _add_prop_name("/ViewArea", [], None)151 cls.view_clip = _add_prop_name("/ViewClip", [], None)152 cls.print_area = _add_prop_name("/PrintArea", [], None)153 cls.print_clip = _add_prop_name("/PrintClip", [], None)154 cls.print_scaling = _add_prop_name("/PrintScaling", [], None)155 cls.duplex = _add_prop_name(156 "/Duplex", ["/Simplex", "/DuplexFlipShortEdge", "/DuplexFlipLongEdge"], None157 )158 cls.pick_tray_by_pdfsize = _add_prop_bool("/PickTrayByPDFSize", None)159 cls.print_pagerange = _add_prop_arr("/PrintPageRange", None)160 cls.num_copies = _add_prop_int("/NumCopies", None)161 162 cls.enforce = _add_prop_arr("/Enforce", ArrayObject())163 164 return cast("ViewerPreferences", DictionaryObject.__new__(cls))165 