1 #include "RichEdit.h"
2 
3 namespace Upp {
4 
UserAction()5 void RichEdit::UserAction()
6 {
7 	useraction = true;
8 }
9 
User(Event<> cb)10 Event<>  RichEdit::User(Event<>  cb)
11 {
12 	cb << THISBACK(UserAction);
13 	return cb;
14 }
15 
16 #define USERBACK(x) User(THISBACK(x))
17 #define USERBACK1(x, y) User(THISBACK1(x, y))
18 
StyleTool(Bar & bar,int width)19 void RichEdit::StyleTool(Bar& bar, int width)
20 {
21 	bar.Add(!IsReadOnly(), style, width);
22 }
23 
FaceTool(Bar & bar,int width)24 void RichEdit::FaceTool(Bar& bar, int width)
25 {
26 	bar.Add(!IsReadOnly(), face, width);
27 }
28 
HeightTool(Bar & bar,int width)29 void RichEdit::HeightTool(Bar& bar, int width)
30 {
31 	bar.Add(!IsReadOnly(), height, width);
32 }
33 
BoldTool(Bar & bar,dword key)34 void RichEdit::BoldTool(Bar& bar, dword key)
35 {
36 	bar.Add(!IsReadOnly(), t_("Bold"),
37 	        formatinfo.charvalid & RichText::BOLD ? RichEditImg::Bold() : RichEditImg::BoldMixed(),
38 	        USERBACK(Bold))
39 	   .Check(formatinfo.IsBold() && (formatinfo.charvalid & RichText::BOLD))
40 	   .Key(key);
41 }
42 
ItalicTool(Bar & bar,dword key)43 void RichEdit::ItalicTool(Bar& bar, dword key)
44 {
45 	bar.Add(!IsReadOnly(), t_("Italic"),
46             formatinfo.charvalid & RichText::ITALIC ? RichEditImg::Italic() : RichEditImg::ItalicMixed(),
47 	        USERBACK(Italic))
48 	   .Check(formatinfo.IsItalic() && (formatinfo.charvalid & RichText::ITALIC))
49 	   .Key(key);
50 }
51 
UnderlineTool(Bar & bar,dword key)52 void RichEdit::UnderlineTool(Bar& bar, dword key)
53 {
54 	bar.Add(!IsReadOnly(), t_("Underline"),
55 	        formatinfo.charvalid & RichText::UNDERLINE ? RichEditImg::Underline()
56 	                                               : RichEditImg::UnderlineMixed(),
57 	        USERBACK(Underline))
58 	   .Check(formatinfo.IsUnderline() && (formatinfo.charvalid & RichText::UNDERLINE))
59 	   .Key(key);
60 }
61 
StrikeoutTool(Bar & bar,dword key)62 void RichEdit::StrikeoutTool(Bar& bar, dword key)
63 {
64 	bar.Add(!IsReadOnly(), t_("Strikeout"),
65 	        formatinfo.charvalid & RichText::STRIKEOUT ? RichEditImg::Strikeout()
66 	                                               : RichEditImg::StrikeoutMixed(),
67 	        USERBACK(Strikeout))
68 	   .Check(formatinfo.IsStrikeout() && (formatinfo.charvalid & RichText::STRIKEOUT))
69 	   .Key(key);
70 }
71 
CapitalsTool(Bar & bar,dword key)72 void RichEdit::CapitalsTool(Bar& bar, dword key)
73 {
74 	bar.Add(!IsReadOnly(), t_("Capitals"),
75 	        formatinfo.charvalid & RichText::CAPITALS  ? RichEditImg::Capitals()
76 	                                               : RichEditImg::CapitalsMixed(),
77 	        USERBACK(Capitals))
78 	   .Check(formatinfo.capitals && (formatinfo.charvalid & RichText::CAPITALS));
79 }
80 
SuperscriptTool(Bar & bar,dword key)81 void RichEdit::SuperscriptTool(Bar& bar, dword key)
82 {
83 	int i = formatinfo.charvalid & RichText::SSCRIPT ? formatinfo.sscript : 0;
84 	bar.Add(!IsReadOnly(), t_("Superscript"),
85 	        formatinfo.charvalid & RichText::SSCRIPT ? RichEditImg::SuperScript()
86 	                                             : RichEditImg::SuperScriptMixed(),
87 			USERBACK1(SetScript, i == 1 ? 0 : 1))
88 	   .Check(i == 1);
89 }
90 
SubscriptTool(Bar & bar,dword key)91 void RichEdit::SubscriptTool(Bar& bar, dword key)
92 {
93 	int i = formatinfo.charvalid & RichText::SSCRIPT ? formatinfo.sscript : 0;
94 	bar.Add(!IsReadOnly(), t_("Subscript"),
95 	        formatinfo.charvalid & RichText::SSCRIPT ? RichEditImg::SubScript()
96 	                                             : RichEditImg::SubScriptMixed(),
97 			USERBACK1(SetScript, i == 2 ? 0 : 2))
98 	   .Check(i == 2);
99 }
100 
FontTools(Bar & bar)101 void RichEdit::FontTools(Bar& bar)
102 {
103 	FaceTool(bar);
104 	bar.Gap(4);
105 	HeightTool(bar);
106 	bar.Gap();
107 	BoldTool(bar);
108 	ItalicTool(bar);
109 	UnderlineTool(bar);
110 	StrikeoutTool(bar);
111 	CapitalsTool(bar);
112 	SuperscriptTool(bar);
113 	SubscriptTool(bar);
114 }
115 
InkTool(Bar & bar)116 void RichEdit::InkTool(Bar& bar)
117 {
118 	bar.Add(!IsReadOnly(), ink);
119 }
120 
PaperTool(Bar & bar)121 void RichEdit::PaperTool(Bar& bar)
122 {
123 	bar.Add(!IsReadOnly(), paper);
124 }
125 
LanguageTool(Bar & bar,int width)126 void RichEdit::LanguageTool(Bar& bar, int width)
127 {
128 	if(!fixedlang)
129 		bar.Add(!IsReadOnly(), language, width);
130 }
131 
SpellCheckTool(Bar & bar)132 void RichEdit::SpellCheckTool(Bar& bar)
133 {
134 	bar.Add(t_("Show spelling errors"), RichEditImg::SpellCheck(), USERBACK(SpellCheck))
135 	   .Check(spellcheck);
136 }
137 
PlusKeyDesc(const char * text,dword key)138 String PlusKeyDesc(const char *text, dword key)
139 {
140 	String r = text;
141 	if(key)
142 		r << ' ' << GetKeyDesc(key);
143 	return r;
144 }
145 
Setup(DataPusher & b,const char * tip,const char * dtip,dword key)146 void Setup(DataPusher& b, const char *tip, const char *dtip, dword key)
147 {
148 	const char *s = tip ? tip : dtip;
149 	b.Tip(PlusKeyDesc(s, key));
150 	b.NullText(s, StdFont().Italic(), SColorDisabled());
151 }
152 
IndexEntryTool(Bar & bar,int width,dword key,const char * tip)153 void RichEdit::IndexEntryTool(Bar& bar, int width, dword key, const char *tip)
154 {
155 	bar.Add(!IsReadOnly(), indexentry, width);
156 	Setup(indexentry, tip, t_("Index entry"), key);
157 	bar.AddKey(key, USERBACK(IndexEntry));
158 }
159 
HyperlinkTool(Bar & bar,int width,dword key,const char * tip)160 void RichEdit::HyperlinkTool(Bar& bar, int width, dword key, const char *tip)
161 {
162 	bar.Add(!IsReadOnly(), hyperlink, width);
163 	Setup(hyperlink, tip, t_("Hyperlink"), key);
164 	bar.AddKey(key, USERBACK(Hyperlink));
165 }
166 
LabelTool(Bar & bar,int width,dword key,const char * tip)167 void RichEdit::LabelTool(Bar& bar, int width, dword key, const char *tip)
168 {
169 	bar.Add(!IsReadOnly(), label, width);
170 	Setup(label, tip, t_("Paragraph label"), key);
171 	bar.AddKey(key, USERBACK(Label));
172 }
173 
LeftTool(Bar & bar,dword key)174 void RichEdit::LeftTool(Bar& bar, dword key)
175 {
176 	int a = formatinfo.paravalid & RichText::ALIGN ? formatinfo.align : Null;
177 	bar.Add(!IsReadOnly(), t_("Left"), RichEditImg::Left(), USERBACK(AlignLeft))
178 	   .Check(a == ALIGN_LEFT)
179 	   .Key(key);
180 }
181 
RightTool(Bar & bar,dword key)182 void RichEdit::RightTool(Bar& bar, dword key)
183 {
184 	int a = formatinfo.paravalid & RichText::ALIGN ? formatinfo.align : Null;
185 	bar.Add(!IsReadOnly(), t_("Right"), RichEditImg::Right(), USERBACK(AlignRight))
186 	   .Check(a == ALIGN_RIGHT)
187 	   .Key(key);
188 }
189 
CenterTool(Bar & bar,dword key)190 void RichEdit::CenterTool(Bar& bar, dword key)
191 {
192 	int a = formatinfo.paravalid & RichText::ALIGN ? formatinfo.align : Null;
193 	bar.Add(!IsReadOnly(), t_("Center"), RichEditImg::Center(), USERBACK(AlignCenter))
194 	   .Check(a == ALIGN_CENTER)
195 	   .Key(key);
196 }
197 
JustifyTool(Bar & bar,dword key)198 void RichEdit::JustifyTool(Bar& bar, dword key)
199 {
200 	int a = formatinfo.paravalid & RichText::ALIGN ? formatinfo.align : Null;
201 	bar.Add(!IsReadOnly(), t_("Justify"), RichEditImg::Justify(), USERBACK(AlignJustify))
202 	   .Check(a == ALIGN_JUSTIFY)
203 	   .Key(key);
204 }
205 
RoundBulletTool(Bar & bar,dword key)206 void  RichEdit::RoundBulletTool(Bar& bar, dword key)
207 {
208 	int a = formatinfo.paravalid & RichText::BULLET ? formatinfo.bullet : Null;
209 	bar.Add(!IsReadOnly(), t_("Round bullet"), RichEditImg::RoundBullet(),
210 	        USERBACK1(SetBullet, RichPara::BULLET_ROUND))
211 	   .Check(a == RichPara::BULLET_ROUND)
212 	   .Key(key);
213 }
214 
RoundWhiteBulletTool(Bar & bar,dword key)215 void  RichEdit::RoundWhiteBulletTool(Bar& bar, dword key)
216 {
217 	int a = formatinfo.paravalid & RichText::BULLET ? formatinfo.bullet : Null;
218 	bar.Add(!IsReadOnly(), t_("White round bullet"), RichEditImg::RoundWhiteBullet(),
219 	        USERBACK1(SetBullet, RichPara::BULLET_ROUNDWHITE))
220 	   .Check(a == RichPara::BULLET_ROUNDWHITE)
221 	   .Key(key);
222 }
223 
BoxBulletTool(Bar & bar,dword key)224 void  RichEdit::BoxBulletTool(Bar& bar, dword key)
225 {
226 	int a = formatinfo.paravalid & RichText::BULLET ? formatinfo.bullet : Null;
227 	bar.Add(!IsReadOnly(), t_("Box bullet"), RichEditImg::BoxBullet(),
228 	        USERBACK1(SetBullet, RichPara::BULLET_BOX))
229 	   .Check(a == RichPara::BULLET_BOX)
230 	   .Key(key);
231 }
232 
BoxWhiteBulletTool(Bar & bar,dword key)233 void  RichEdit::BoxWhiteBulletTool(Bar& bar, dword key)
234 {
235 	int a = formatinfo.paravalid & RichText::BULLET ? formatinfo.bullet : Null;
236 	bar.Add(!IsReadOnly(), t_("White box bullet"), RichEditImg::BoxWhiteBullet(),
237 	        USERBACK1(SetBullet, RichPara::BULLET_BOXWHITE))
238 	   .Check(a == RichPara::BULLET_BOXWHITE)
239 	   .Key(key);
240 }
241 
TextBulletTool(Bar & bar,dword key)242 void  RichEdit::TextBulletTool(Bar& bar, dword key)
243 {
244 	int a = formatinfo.paravalid & RichText::BULLET ? formatinfo.bullet : Null;
245 	bar.Add(!IsReadOnly(), t_("Text bullet"), RichEditImg::TextBullet(),
246 	        USERBACK1(SetBullet, RichPara::BULLET_TEXT))
247 	   .Check(a == RichPara::BULLET_TEXT)
248 	   .Key(key);
249 }
250 
ParaFormatTool(Bar & bar,dword key)251 void RichEdit::ParaFormatTool(Bar& bar, dword key)
252 {
253 	bar.Add(!IsReadOnly(), t_("Paragraph format.."), RichEditImg::ParaFormat(), USERBACK(ParaFormat))
254 	   .Key(key);
255 }
256 
ToParaTool(Bar & bar,dword key)257 void RichEdit::ToParaTool(Bar& bar, dword key)
258 {
259 	bar.Add(!IsReadOnly() && IsSelection() && !tablesel, t_("To single paragraph"),
260 	        RichEditImg::ToPara(), USERBACK(ToPara))
261 	   .Key(key);
262 }
263 
ParaTools(Bar & bar)264 void RichEdit::ParaTools(Bar& bar)
265 {
266 	LeftTool(bar);
267 	CenterTool(bar);
268 	RightTool(bar);
269 	JustifyTool(bar);
270 	bar.Gap();
271 	RoundBulletTool(bar);
272 	RoundWhiteBulletTool(bar);
273 	BoxBulletTool(bar);
274 	BoxWhiteBulletTool(bar);
275 	TextBulletTool(bar);
276 	bar.Gap();
277 	ToParaTool(bar);
278 	bar.Gap();
279 	ParaFormatTool(bar);
280 }
281 
UndoTool(Bar & bar,dword key)282 void RichEdit::UndoTool(Bar& bar, dword key)
283 {
284 	bar.Add(!IsReadOnly() && undo.GetCount(), t_("Undo"), CtrlImg::undo(), USERBACK(Undo))
285 	   .Repeat()
286 	   .Key(K_ALT_BACKSPACE)
287 	   .Key(key);
288 }
289 
RedoTool(Bar & bar,dword key)290 void RichEdit::RedoTool(Bar& bar, dword key)
291 {
292 	bar.Add(!IsReadOnly() && redo.GetCount(), t_("Redo"), CtrlImg::redo(), USERBACK(Redo))
293 	   .Repeat()
294 	   .Key(K_SHIFT|K_ALT_BACKSPACE)
295 	   .Key(key);
296 }
297 
CutTool(Bar & bar,dword key)298 void RichEdit::CutTool(Bar& bar, dword key)
299 {
300 	bar.Add(!IsReadOnly() && IsSelection() || objectpos >= 0, t_("Cut"), CtrlImg::cut(), USERBACK(Cut))
301 	   .Key(K_SHIFT_DELETE)
302 	   .Key(key);
303 }
304 
CopyTool(Bar & bar,dword key)305 void RichEdit::CopyTool(Bar& bar, dword key)
306 {
307 	bar.Add(IsSelection() || objectpos >= 0,
308 	        t_("Copy"), CtrlImg::copy(), USERBACK(Copy))
309 	   .Key(K_CTRL_INSERT)
310 	   .Key(key);
311 }
312 
PasteTool(Bar & bar,dword key)313 void RichEdit::PasteTool(Bar& bar, dword key)
314 {
315 	bar.Add(!IsReadOnly(), t_("Paste"), CtrlImg::paste(), USERBACK(Paste))
316 	   .Key(K_SHIFT_INSERT)
317 	   .Key(key);
318 }
319 
ObjectTool(Bar & bar,dword key)320 void RichEdit::ObjectTool(Bar& bar, dword key)
321 {
322 	for(int i = 0; i < RichObject::GetTypeCount(); i++) {
323 		String cn = RichObject::GetType(i).GetCreateName();
324 		if(!IsNull(cn))
325 			bar.Add(cn, USERBACK1(InsertObject, i));
326 	}
327 }
328 
LoadImageTool(Bar & bar,dword key)329 void RichEdit::LoadImageTool(Bar& bar, dword key)
330 {
331 	bar.Add(!IsReadOnly(), t_("Insert image from file.."), RichEditImg::LoadImageFile(), THISBACK(InsertImage));
332 }
333 
PrintTool(Bar & bar,dword key)334 void RichEdit::PrintTool(Bar& bar, dword key)
335 {
336 	bar.Add(t_("Print"), CtrlImg::print(), USERBACK(DoPrint))
337 	   .Key(key);
338 }
339 
FindReplaceTool(Bar & bar,dword key)340 void RichEdit::FindReplaceTool(Bar& bar, dword key)
341 {
342 	bar.Add(!IsReadOnly(), t_("Find/Replace"), RichEditImg::FindReplace(), USERBACK(OpenFindReplace))
343 	   .Key(key);
344 }
345 
EditTools(Bar & bar)346 void RichEdit::EditTools(Bar& bar)
347 {
348 	CutTool(bar);
349 	CopyTool(bar);
350 	PasteTool(bar);
351 	bar.Gap();
352 	UndoTool(bar);
353 	RedoTool(bar);
354 	bar.Gap();
355 	FindReplaceTool(bar);
356 }
357 
InsertTableTool(Bar & bar,dword key)358 void RichEdit::InsertTableTool(Bar& bar, dword key)
359 {
360 	bar.Add(!IsSelection() && !IsReadOnly(),
361 	        t_("Insert table.."), RichEditImg::InsertTable(), USERBACK(InsertTable))
362 	   .Key(key);
363 }
364 
TablePropertiesTool(Bar & bar,dword key)365 void RichEdit::TablePropertiesTool(Bar& bar, dword key)
366 {
367 	bar.Add(!IsSelection() && cursorp.table && !IsReadOnly(),
368 	        t_("Table properties.."), RichEditImg::TableProperties(),
369 	        USERBACK(TableProps))
370 	   .Key(key);
371 }
372 
InsertTableRowTool(Bar & bar,dword key)373 void RichEdit::InsertTableRowTool(Bar& bar, dword key)
374 {
375 	bar.Add(!IsSelection() && cursorp.table && !IsReadOnly(),
376 	        t_("Insert row"), RichEditImg::TableInsertRow(),
377 	        USERBACK(TableInsertRow))
378 	   .Key(key);
379 }
380 
RemoveTableRowTool(Bar & bar,dword key)381 void RichEdit::RemoveTableRowTool(Bar& bar, dword key)
382 {
383 	bar.Add(!IsSelection() && cursorp.table && !IsReadOnly(),
384 	        t_("Remove row"), RichEditImg::TableRemoveRow(), USERBACK(TableRemoveRow))
385 	   .Key(key);
386 }
387 
InsertTableColumnTool(Bar & bar,dword key)388 void RichEdit::InsertTableColumnTool(Bar& bar, dword key)
389 {
390 	bar.Add(!IsSelection() && cursorp.table && !IsReadOnly(),
391 	        t_("Insert column"), RichEditImg::TableInsertColumn(),
392 	        USERBACK(TableInsertColumn))
393 	   .Key(key);
394 }
395 
RemoveTableColumnTool(Bar & bar,dword key)396 void RichEdit::RemoveTableColumnTool(Bar& bar, dword key)
397 {
398 	bar.Add(!IsSelection() && cursorp.table && !IsReadOnly(),
399 	        t_("Remove column"), RichEditImg::TableRemoveColumn(), USERBACK(TableRemoveColumn))
400 	   .Key(key);
401 }
402 
SplitJoinCellTool(Bar & bar,dword key)403 void RichEdit::SplitJoinCellTool(Bar& bar, dword key)
404 {
405 	if(tablesel)
406 		bar.Add(!IsReadOnly(), t_("Join cells"), RichEditImg::JoinCell(), USERBACK(JoinCell))
407 		   .Key(key);
408 	else
409 		bar.Add(!IsSelection() && cursorp.table && !IsReadOnly(), t_("Split cell.."),
410 		        RichEditImg::SplitCell(), USERBACK(SplitCell))
411 		   .Key(key);
412 }
413 
CellPropertiesTool(Bar & bar,dword key)414 void RichEdit::CellPropertiesTool(Bar& bar, dword key)
415 {
416 	bar.Add(cursorp.table && (!IsSelection() || tablesel) && !IsReadOnly(),
417 	        t_("Cell properties.."), RichEditImg::CellProperties(), USERBACK(CellProperties))
418 	   .Key(key);
419 }
420 
TableTools(Bar & bar)421 void RichEdit::TableTools(Bar& bar)
422 {
423 	InsertTableTool(bar);
424 	TablePropertiesTool(bar);
425 	InsertTableRowTool(bar);
426 	RemoveTableRowTool(bar);
427 	InsertTableColumnTool(bar);
428 	RemoveTableColumnTool(bar);
429 	SplitJoinCellTool(bar);
430 	CellPropertiesTool(bar);
431 }
432 
InsertImageTool(Bar & bar)433 void RichEdit::InsertImageTool(Bar& bar)
434 {
435 	bar.Add(t_("Insert image from file.."), USERBACK(InsertImage));
436 }
437 
StyleKeysTool(Bar & bar)438 void RichEdit::StyleKeysTool(Bar& bar)
439 {
440 	bar.Add(t_("Style keys.."), USERBACK(StyleKeys));
441 }
442 
HeaderFooterTool(Bar & bar)443 void RichEdit::HeaderFooterTool(Bar& bar)
444 {
445 	bar.Add(t_("Header/Footer.."), RichEditImg::HeaderFooter(), USERBACK(HeaderFooter));
446 }
447 
DefaultBar(Bar & bar,bool extended)448 void RichEdit::DefaultBar(Bar& bar, bool extended)
449 {
450 	EditTools(bar);
451 	bar.Gap();
452 	PrintTool(bar);
453 	bar.Gap();
454 	FontTools(bar);
455 	bar.Gap();
456 	InkTool(bar);
457 	PaperTool(bar);
458 	bar.Gap();
459 	LanguageTool(bar);
460 	SpellCheckTool(bar);
461 	if(extended) {
462 		bar.Gap();
463 		IndexEntryTool(bar, INT_MAX);
464 	}
465 	bar.Break();
466 	StyleTool(bar);
467 	bar.Gap();
468 	ParaTools(bar);
469 	if(extended) {
470 		bar.Gap();
471 		HeaderFooterTool(bar);
472 	}
473 	bar.Gap();
474 	if(extended) {
475 		LabelTool(bar);
476 		bar.Gap();
477 	}
478 	TableTools(bar);
479 	if(extended) {
480 		bar.Gap();
481 		HyperlinkTool(bar, INT_MAX);
482 	}
483 }
484 
485 }
486