1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_SVX_TEXTCHAIN_HXX
21 #define INCLUDED_SVX_TEXTCHAIN_HXX
22 
23 #include <editeng/editdata.hxx>
24 #include <map>
25 
26 /*
27  * Properties can be accessed and set from a TextChain with:
28  * - T TextChain::GetPROPNAME(SdrTextObj *)
29  * - void TextChain::SetPROPNAME(SdrTextObj *, T)
30  * where T and PROPNAME are respectively type and name of a property.
31  *
32  * To add a property PROPNAME of type T (and its interface) in TextChain:
33  * 1) Add
34  *      "DECL_CHAIN_PROP(PROPNAME, T)"
35  *    in class ImpChainLinkProperties;
36  * 2) Add
37  *      "INIT_CHAIN_PROP(PROPNAME, V)"
38  *    in constructor of ImpChainLinkProperties below
39  *    (V is the initialization value for PROPNAME)
40  *
41  * 3) Add
42  *      "DECL_CHAIN_PROP_INTERFACE(PROPNAME, T)"
43  *    in class TextChain (under "public:");
44  * 4)  Add
45  *       "IMPL_CHAIN_PROP_INTERFACE(PROPNAME, T)"
46  *    in file "svx/source/svdraw/textchain.cxx"
47 */
48 
49 #define DECL_CHAIN_PROP(PropName, PropType) \
50     PropType a##PropName;
51 
52 #define INIT_CHAIN_PROP(PropName, PropDefault) \
53     a##PropName = (PropDefault);
54 
55 #define DECL_CHAIN_PROP_INTERFACE(PropName, PropType) \
56     PropType const & Get##PropName (const SdrTextObj *); \
57     void Set##PropName (const SdrTextObj *, PropType);
58 
59 #define IMPL_CHAIN_PROP_INTERFACE(PropName, PropType) \
60     PropType const & TextChain::Get##PropName (const SdrTextObj *pTarget) { \
61         ImpChainLinkProperties *pLinkProperties = GetLinkProperties(pTarget); \
62         return pLinkProperties->a##PropName; \
63     } \
64     void TextChain::Set##PropName (const SdrTextObj *pTarget, PropType aPropParam) \
65     { \
66         ImpChainLinkProperties *pLinkProperties = GetLinkProperties(pTarget); \
67         pLinkProperties->a##PropName = aPropParam; \
68     }
69 
70 /* End Special Properties Macro */
71 
72 
73 class ImpChainLinkProperties;
74 class SdrTextObj;
75 class SdrModel;
76 
77 namespace rtl {
78     class OUString;
79 }
80 
81 typedef OUString ChainLinkId;
82 
83 enum class CursorChainingEvent
84 {
85     TO_NEXT_LINK,
86     TO_PREV_LINK,
87     UNCHANGED,
88     NULL_EVENT
89 };
90 
91 class ImpChainLinkProperties
92 {
93 protected:
94     friend class TextChain;
95 
ImpChainLinkProperties()96     ImpChainLinkProperties() {
97         INIT_CHAIN_PROP(NilChainingEvent, false)
98         INIT_CHAIN_PROP(CursorEvent, CursorChainingEvent::NULL_EVENT)
99         INIT_CHAIN_PROP(PreChainingSel, ESelection(0,0,0,0));
100         INIT_CHAIN_PROP(PostChainingSel, ESelection(0,0,0,0));
101         INIT_CHAIN_PROP(IsPartOfLastParaInNextLink, false) // XXX: Should come from file
102         INIT_CHAIN_PROP(PendingOverflowCheck, false)
103         INIT_CHAIN_PROP(SwitchingToNextBox, false)
104     }
105 
106 private:
107     // NOTE: Remember to set default value in constructor when adding field
108     DECL_CHAIN_PROP(NilChainingEvent, bool)
109     DECL_CHAIN_PROP(CursorEvent, CursorChainingEvent)
110     DECL_CHAIN_PROP(PreChainingSel, ESelection)
111     DECL_CHAIN_PROP(PostChainingSel, ESelection)
112     DECL_CHAIN_PROP(IsPartOfLastParaInNextLink, bool)
113     DECL_CHAIN_PROP(PendingOverflowCheck, bool)
114     DECL_CHAIN_PROP(SwitchingToNextBox, bool)
115 };
116 
117 
118 class TextChain
119 {
120 public:
121     ~TextChain();
122 
123     //void AppendLink(SdrTextObj *);
124     //bool IsLinkInChain(SdrTextObj *) const;
125 
126     //SdrTextObj *GetNextLink(const SdrTextObj *) const;
127     //SdrTextObj *GetPrevLink(const SdrTextObj *) const;
128 
129     ImpChainLinkProperties *GetLinkProperties(const SdrTextObj *);
130 
131     // Specific Link Properties
132     DECL_CHAIN_PROP_INTERFACE(CursorEvent, CursorChainingEvent)
133     DECL_CHAIN_PROP_INTERFACE(NilChainingEvent, bool)
134     DECL_CHAIN_PROP_INTERFACE(PreChainingSel, ESelection)
135     DECL_CHAIN_PROP_INTERFACE(PostChainingSel, ESelection)
136     // return whether a paragraph is split between this box and the next
137     DECL_CHAIN_PROP_INTERFACE(IsPartOfLastParaInNextLink, bool)
138     // return whether there is a pending overflow check (usually when we move cursor after an overflow in the prev link)
139     DECL_CHAIN_PROP_INTERFACE(PendingOverflowCheck, bool)
140     // return whether we are currently moving the cursor to the next box (useful to know whether we should prevent SetOutlinerParaObject invocations in SdrTextObj::EndTextEdit)
141     DECL_CHAIN_PROP_INTERFACE(SwitchingToNextBox, bool)
142 
143 protected:
144     TextChain();
145 
146 private:
147     std::map< ChainLinkId, ImpChainLinkProperties *> maLinkPropertiesMap;
148 
149     friend class SdrModel;
150     //SdrTextObj *impGetNextLink(const SdrTextObj *) const;
151     //SdrTextObj *impGetPrevLink(const SdrTextObj *) const;
152 };
153 
154 #endif // INCLUDED_SVX_TEXTCHAIN_HXX
155 
156 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
157