1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! ## 2.2.10 UserForm Control
//!
//! Excerpt from the docs:
//!
//! > All parent controls MUST contain a FormControl. The FormControl properties are persisted to a stream as specified in section 2.1.1.2. The name of this stream MUST be "f". An OleSiteConcrete is persisted in this stream for each embedded control, as specified by the FormControl in section 2.2.10.12. The FormControl can also contain a DesignExtender, as specified in section 2.2.10.11.

pub mod class_table;
pub mod designex;
pub mod ole_site_concrete;
mod parser;

use crate::properties::{
    color::OleColor, font::GuidAndFont, picture::GuidAndPicture, MousePointer, PictureAlignment,
    PictureSizeMode, Position, Size, SpecialEffect,
};
use class_table::{ClsTableFlags, SiteClassInfo};
use ole_site_concrete::OleSiteConcreteControl;

pub use parser::*;
pub mod stream;

bitflags! {
    /// A bit field that specifies Boolean properties of a form.
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub struct FormFlags: u32 {
        /// Specifies whether the form is enabled.
        const ENABLED               = 0x00000004;
        /// Specifies whether Design Extender properties are persisted with this form.
        const DESINKPERSISTED       = 0x00004000;
        /// Specifies whether the Class Table of a form is not persisted. A value of zero specifies that the Class Table is persisted if it is not empty.
        const DONTSAVECLASSTABLE    = 0x00008000;
    }
}

#[repr(u8)]
#[derive(Debug, FromPrimitive, ToPrimitive)]
pub enum BorderStyle {
    /// The control has no visible border line.
    None = 0x00,
    /// The control has a single-line border.
    Single = 0x01,
}

/// Specifies the behavior of the TAB key in the last control of a form
#[repr(u8)]
#[derive(Debug, FromPrimitive, ToPrimitive)]
pub enum Cycle {
    /// The focus is next set to the first control on the next form, returning to the first control of this form only after all controls on all other forms have been reached.
    AllForms = 0x00,
    /// The focus is next set to the first control on this form, ignoring other forms.
    CurrentForm = 0x02,
}

bitflags! {
    /// A bit field that specifies the location of the scroll bars of a form.
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub struct FormScrollBarFlags: u8 {
        /// Specifies whether the horizontal scroll bar is displayed.
        const HORIZONTAL = 0x01;
        /// Specifies whether the vertical scroll bar is displayed.
        const VERTICAL = 0x02;
        /// Specifies whether to display the horizontal scroll bar at all times, even when all controls are visible without scrolling.
        const KEEP_HORIZONTAL = 0x04;
        /// Specifies whether to display the vertical scroll bar at all times, even when all controls are visible without scrolling.
        const KEEP_VERTICAL = 0x08;
        /// Specifies whether to display the vertical scroll bar on the left side of the form.
        const KEEP_LEFT = 0x10;
        /// The default value
        const DEFAULT = Self::KEEP_HORIZONTAL.bits() | Self::KEEP_VERTICAL.bits();
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Site {
    pub depth: u8,
    pub kind: SiteKind,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SiteKind {
    Ole(OleSiteConcreteControl),
}

#[derive(Debug)]
pub struct FormControl {
    /// default: 0x8000000F = COLOR_BTNFACE from the system palette.
    pub back_color: OleColor,
    /// default: 0x00000004 = FORM_FLAG_ENABLED
    pub boolean_properties: FormFlags,
    /// default: 0x80000012 = COLOR_BTNTEXT from the system palette.
    pub border_color: OleColor,
    /// default: 0x00 = None
    pub border_style: BorderStyle,
    /// default: ""
    pub caption: String,
    /// default: AllForms
    pub cycle: Cycle,
    /// default: (4000, 3000)
    pub displayed_size: Size,
    /// REQUIRED
    pub draw_buffer: u32,
    /// default: no font
    pub font: GuidAndFont,
    /// default: 0x80000012 = COLOR_BTNTEXT from the system palette
    pub fore_color: OleColor,
    /// An unsigned integer that specifies the number of control groups on a form. default: 0
    pub group_count: u32,
    /// An fmSize that specifies the full scrollable size, in HIMETRIC units, of a form, including all controls. A value of zero in either width or height specifies that the scrollable size is equivalent to the value of the corresponding portion of DisplayedSize.
    ///
    /// default: (4000, 3000)
    pub logical_size: Size,
    /// A GuidAndPicture that specifies a custom icon to display as the mouse pointer for the control, which is used when the value of the MousePointer property is set to 99, fmMousePointerCustom.
    ///
    /// The file format default is no custom icon.
    pub mouse_icon: GuidAndPicture,
    /// An unsigned integer that specifies the type of icon displayed as the mouse pointer for the control. SHOULD be a value from the fmMousePointer enumeration.<8>
    ///
    /// The file format default is 0x00, fmMousePointerDefault.
    pub mouse_pointer: MousePointer,
    /// An unsigned integer that specifies the largest ID that has been used by an embedded control on a form. The value of this property can be used by the client application to determine the next valid ID for a new control.
    ///
    /// The file format default is 0x00000000.
    pub next_available_id: u32,
    /// A GuidAndPicture that specifies the picture to display on a control.
    ///
    /// The file format default is no picture.
    pub picture: GuidAndPicture,

    /// An fmPictureAlignment that specifies the alignment of the picture in the Form or Image.
    ///
    /// The file format default is 0x02, fmPictureAlignmentCenter.
    pub picture_alignment: PictureAlignment,
    /// An fmPictureSizeMode that specifies how to display the picture.
    ///
    /// The file format default is 0x00, fmPictureSizeModeClip.
    pub picture_size_mode: PictureSizeMode,
    /// A Boolean value that specifies whether the picture is tiled across the background.
    ///
    /// The file format default is FALSE.
    pub picture_tiling: bool,
    /// A FormScrollBarFlags that specifies whether a form has vertical or horizontal scroll bars and when to display them.
    ///
    /// The file format default is 0x0000000C, fScrollBarsKeepHorizontal and fScrollBarsKeepVertical.
    pub scroll_bars: FormScrollBarFlags,
    /// An fmPosition that specifies, in HIMETRIC units, the coordinates of the first point in the LogicalSize of the form that is visible.
    ///
    /// The file format default is a position of (0, 0), which specifies that the form has not been scrolled.
    pub scroll_position: Position,
    /// An unsigned integer that specifies the number of times the dynamic type information of a form has changed. The value of this property can be used to determine whether a form being loaded still matches the dynamic type information against which it was compiled.
    ///
    /// The file format default is 0x00000000.
    pub shape_cookie: u32,
    /// An fmSpecialEffect that specifies the visual appearance of the control.
    ///
    /// The file format default is  0x00, fmSpecialEffectFlat
    pub special_effect: SpecialEffect,
    /// A signed integer that specifies the magnification of embedded controls, in percentage points of the size of the parent control. MUST be greater than or equal to 10 (10 percent of actual size) and less than or equal to 400 (four times or 400 percent of actual size).
    ///
    /// The file format default is 100, or actual size.
    pub zoom: u32,
    /// All contained sites
    pub sites: Vec<Site>,

    /// All contained site classes
    pub site_classes: Vec<SiteClassInfo>,
}