RichTextView.cpp

Added Enable statment - Zbigniew Rebacz, 12/29/2013 02:17 PM

Download (9.71 KB)

 
1
#include "CtrlLib.h"
2

    
3
NAMESPACE_UPP
4

    
5
#define LLOG(x) // LOG(x)
6

    
7
Rect  RichTextView::GetPage() const
8
{
9
        return Rect(0, 0, GetPageCx(), INT_MAX);
10
}
11

    
12
void  RichTextView::Paint(Draw& w)
13
{
14
        Size sz = GetSize();
15
        w.DrawRect(sz, background);
16
        sz.cx -= margin.left + margin.right;
17
        sz.cy -= margin.top + margin.bottom;
18
        w.Clipoff(margin.left, margin.top, sz.cx, sz.cy);
19
        PaintInfo pi;
20
        if(!hldec)
21
                pi.hyperlink = Null;
22
        if(sell < selh) {
23
                pi.sell = sell;
24
                pi.selh = selh;
25
        }
26
        pi.indexentry = Null;
27
        pi.highlightpara = highlight;
28
        pi.zoom = GetZoom();
29
        int q = sb * pi.zoom;
30
        scroller.Set(q);
31
        w.Offset(0, -q);
32
        SimplePageDraw pw(w);
33
        pi.top = PageY(0, sb);
34
        pi.bottom = PageY(0, sb + sz.cy / pi.zoom);
35
        pi.usecache = true;
36
        pi.sizetracking = sizetracking;
37
        pi.shrink_oversized_objects = shrink_oversized_objects;
38
        Color c = SColorPaper();
39
        if(Grayscale(c) < 100)
40
                pi.coloroverride = true;
41
        text.Paint(pw, GetPage(), pi);
42
        w.End();
43
        w.End();
44
}
45

    
46
Zoom  RichTextView::GetZoom() const
47
{
48
        int szcx = GetSize().cx;
49
        if(!sb.IsShown() && sb.IsAutoHide())
50
                szcx -= ScrollBarSize();
51
        return IsNull(zoom) ? Zoom(szcx - margin.left - margin.right, cx) : zoom;
52
}
53

    
54
int   RichTextView::GetPageCx(bool reduced) const
55
{
56
        int szcx = GetSize().cx;
57
        if(reduced && !sb.IsShown() && sb.IsAutoHide())
58
                szcx -= ScrollBarSize();
59
        return IsNull(zoom) ? cx : (szcx - margin.left - margin.right) / zoom;
60
}
61

    
62
void  RichTextView::SetSb()
63
{
64
        Rect page(0, 0, GetPageCx(true), INT_MAX);
65
        PageY py = text.GetHeight(page);
66
        sb.SetTotal(py.y);
67
        sb.SetPage((GetSize().cy - margin.top - margin.bottom) / GetZoom());
68
}
69

    
70
bool  RichTextView::Key(dword key, int count)
71
{
72
        if(key == K_CTRL_C || key == K_SHIFT_INSERT) {
73
                Copy();
74
                return true;
75
        }
76
        return sb.VertKey(key);
77
}
78

    
79
void  RichTextView::MouseWheel(Point p, int zdelta, dword keyflags)
80
{
81
        sb.Wheel(zdelta);
82
}
83

    
84
Image RichTextView::CursorImage(Point p, dword keyflags)
85
{
86
        int pos = GetPointPos(p);
87
        if(WhenLink && pos >= 0 && !IsNull(GetLink(pos, p)))
88
                return Image::Hand();
89
        if(HasCapture())
90
                return Image::IBeam();
91
        return Image::Arrow();
92
}
93

    
94
void RichTextView::Copy()
95
{
96
        if(anchor == cursor)
97
                WriteClipboardUnicodeText(text.GetPlainText());
98
        else {
99
                RefreshSel();
100
                WString h = text.GetPlainText(false).Mid(sell, selh - sell);
101
                WString r;
102
                for(const wchar *s = ~h; s < h.End(); s++) {
103
                        if(*s == '\n')
104
                                r.Cat('\r');
105
                        r.Cat(*s);
106
                }
107
                WriteClipboardUnicodeText(r);
108
        }
109
}
110

    
111
void RichTextView::RightDown(Point p, dword keyflags)
112
{
113
        MenuBar b;
114
        b.Add(t_("Copy"), CtrlImg::copy(), THISBACK(Copy)).Key(K_CTRL_C).Enable(cursor != anchor);
115
        b.Execute();
116
}
117

    
118
int  RichTextView::GetPointPos(Point p) const
119
{
120
        Size sz = GetSize();
121
        sz.cx -= margin.left + margin.right;
122
        sz.cy -= margin.top + margin.bottom;
123
        p -= margin.TopLeft();
124
        Zoom zoom = GetZoom();
125
        p.y += sb * zoom;
126
        return text.GetPos(p.x / zoom, PageY(0, p.y / zoom), GetPage());
127
}
128

    
129
String RichTextView::GetLink(int pos, Point p) const
130
{
131
        String link;
132
        RichObject object = text.GetRichPos(pos).object;
133
        if(object) {
134
                Rect rc = text.GetCaret(pos, GetPage());
135
                link = object.GetLink(p - rc.TopLeft(), rc.Size());
136
        }
137

    
138
        if(IsNull(link)) {
139
                RichPos richpos = text.GetRichPos(pos);
140
                if(richpos.chr != '\n')
141
                        link = Nvl(richpos.fieldformat.link, richpos.format.link);
142
        }
143
        return link;
144
}
145

    
146
void RichTextView::RefreshRange(int a, int b)
147
{
148
        int l = min(a, b);
149
        int h = max(a, b);
150
        if(l == h)
151
                return;
152
        Rect r1 = text.GetCaret(l, GetPage());
153
        Rect r2 = text.GetCaret(h, GetPage());
154
        Zoom zoom = GetZoom();
155
        Refresh(0, zoom * (r1.top - sb), GetSize().cx, zoom * (r2.bottom - sb + zoom.d - 1));
156
}
157

    
158
void  RichTextView::RefreshSel()
159
{
160
        int l = minmax(min(cursor, anchor), 0, text.GetLength());
161
        int h = minmax(max(cursor, anchor), 0, text.GetLength());
162
        if(sell == l && selh == h || sell == selh && l == h)
163
                return;
164
        RichPos pl = text.GetRichPos(l);
165
        RichPos ph = text.GetRichPos(h);
166
        RichPos psell = text.GetRichPos(sell);
167
        RichPos pselh = text.GetRichPos(selh);
168
        if(psell.parai != pl.parai || pselh.parai != ph.parai ||
169
           psell.table != pl.table || pselh.table != ph.table ||
170
           psell.cell != pl.cell || pselh.cell != ph.cell)
171
                Refresh();
172
        else {
173
                RefreshRange(l, sell);
174
                RefreshRange(h, selh);
175
        }
176
        sell = l;
177
        selh = h;
178
}
179

    
180
void  RichTextView::LeftDown(Point p, dword keyflags)
181
{
182
        int pos = GetPointPos(p);
183
        if(pos < 0) {
184
                cursor = anchor = 0;
185
                return;
186
        }
187
        String link = GetLink(pos, p);
188
        if(!IsNull(link))
189
                WhenLink(link);
190
        else {
191
                cursor = pos;
192
                if(!(keyflags & K_SHIFT))
193
                        anchor = pos;
194
                RefreshSel();
195
                SetFocus();
196
                SetCapture();
197
        }
198
}
199

    
200
void RichTextView::LeftDouble(Point p, dword keyflags)
201
{
202
        int pos = GetPointPos(p);
203
        if(IsLeNum(text[pos])) {
204
                anchor = pos;
205
                while(anchor > 0 && IsLeNum(text[anchor - 1]))
206
                        anchor--;
207
                cursor = pos;
208
                while(cursor + 1 < text.GetLength() && IsLeNum(text[cursor]))
209
                        cursor++;
210
                while(cursor + 1 < text.GetLength() && text[cursor] == ' ')
211
                        cursor++;
212
                RefreshSel();
213
                SetFocus();
214
        }
215
}
216

    
217
void RichTextView::LeftTriple(Point p, dword keyflags)
218
{
219
    int pos = GetPointPos(p);
220
        RichPos rp = text.GetRichPos(pos);
221
        anchor = pos - rp.posinpara;
222
        cursor = anchor + rp.paralen + 1;
223
    RefreshSel();
224
    SetFocus();
225
}
226

    
227
void RichTextView::MouseMove(Point p, dword keyflags)
228
{
229
        int pos = GetPointPos(p);
230
        WhenMouseMove(pos);
231
        if(HasCapture()) {
232
                if(pos < 0)
233
                        return;
234
                cursor = pos;
235
                Rect r1 = text.GetCaret(cursor, GetPage());
236
                sb.ScrollInto(r1.top, r1.Height());
237
                RefreshSel();
238
        }
239
}
240

    
241
void RichTextView::LeftRepeat(Point p, dword keyflags)
242
{
243
        MouseMove(p, keyflags);
244
}
245

    
246
void  RichTextView::EndSizeTracking()
247
{
248
        sizetracking = false;
249
        Refresh();
250
}
251

    
252
void  RichTextView::Layout()
253
{
254
        sizetracking = false;
255
        if(IsOpen() && lazy) {
256
                sizetracking = true;
257
                KillTimeCallback(TIMEID_ENDSIZETRACKING);
258
                SetTimeCallback(250, THISBACK(EndSizeTracking), TIMEID_ENDSIZETRACKING);
259
        }
260
        SetSb();
261
        Refresh();
262
}
263

    
264
Value RichTextView::GetData() const
265
{
266
        if(text.IsEmpty()) return Value();
267
        return GetQTF();
268
}
269

    
270
void  RichTextView::SetData(const Value& v)
271
{
272
        SetQTF(String(v));
273
}
274

    
275
void  RichTextView::Scroll()
276
{
277
        scroller.Scroll(*this, Rect(GetSize()).Deflated(margin), sb * GetZoom());
278
}
279

    
280
void RichTextView::GotoLabel(const String& lbl, bool dohighlight)
281
{
282
        Vector<RichValPos> f = text.GetValPos(GetPage(), RichText::LABELS);
283
        highlight = Null;
284
        for(int i = 0; i < f.GetCount(); i++) {
285
                if(f[i].data == WString(lbl)) {
286
                        sb = f[i].py.y;
287
                        if(dohighlight)
288
                                highlight = f[i].pos;
289
                        Refresh();
290
                        break;
291
                }
292
        }
293
}
294

    
295
void  RichTextView::Clear()
296
{
297
        sb = 0;
298
        text.Clear();
299
        SetSb();
300
        Refresh();
301
        anchor = cursor = sell = selh = 0;
302
}
303

    
304
void  RichTextView::Pick(pick_ RichText& rt)
305
{
306
        sb = 0;
307
        anchor = cursor = sell = selh = 0;
308
        text = rt;
309
        SetSb();
310
        UpdateRefresh();
311
        highlight = -1;
312
}
313

    
314
void  RichTextView::Pick(pick_ RichText& txt, Zoom z) {
315
        if(z.m != z.d)
316
                const_cast<RichText&>(txt).ApplyZoom(z);
317
        Pick(txt);
318
        sb.SetLine(z * 100);
319
}
320

    
321
void  RichTextView::SetQTF(const char *qtf, Zoom z)
322
{
323
        Pick(ParseQTF(qtf), z);
324
}
325

    
326
RichTextView& RichTextView::PageWidth(int _cx)
327
{
328
        cx = _cx;
329
        sb = 0;
330
        SetSb();
331
        Refresh();
332
        return *this;
333
}
334

    
335
RichTextView& RichTextView::SetZoom(Zoom z)
336
{
337
        zoom = z;
338
        sb = 0;
339
        SetSb();
340
        Refresh();
341
        return *this;
342
}
343

    
344
RichTextView& RichTextView::Background(Color c)
345
{
346
        background = c;
347
        Transparent(IsNull(c));
348
        Refresh();
349
        return *this;
350
}
351

    
352
RichTextView& RichTextView::VCenter(bool b)
353
{
354
        vcenter = b;
355
        return *this;
356
}
357

    
358
RichTextView& RichTextView::Margins(const Rect& m)
359
{
360
        margin = m;
361
        Refresh();
362
        return *this;
363
}
364

    
365
RichTextView& RichTextView::HMargins(int a)
366
{
367
        margin.left = margin.right = a;
368
        Refresh();
369
        return *this;
370
}
371

    
372
RichTextView& RichTextView::VMargins(int a)
373
{
374
        margin.top = margin.bottom = a;
375
        Refresh();
376
        return *this;
377
}
378

    
379
RichTextView& RichTextView::Margins(int a)
380
{
381
        margin.Set(a, a, a, a);
382
        Refresh();
383
        return *this;
384
}
385

    
386
void LinkInRichTextClipboard__();
387

    
388
RichTextView::RichTextView()
389
{
390
        cx = 3968;
391
        sizetracking = false;
392
        sb.SetLine(100);
393
        sb.WhenScroll = THISBACK(Scroll);
394
        zoom = Null;
395
        background = SColorPaper;
396
        vcenter = false;
397
        margin = Rect(0, 0, 0, 0);
398
        highlight = -1;
399
        hldec = true;
400
        WhenLink = callback(LaunchWebBrowser);
401
        anchor = cursor = sell = selh = 0;
402
        SetFrame(ViewFrame());
403
        AddFrame(sb);
404
        NoWantFocus();
405
        lazy = true;
406
        shrink_oversized_objects = true;
407
}
408

    
409
RichTextView::~RichTextView() {}
410

    
411
void RichTextCtrl::SetData(const Value& v)
412
{
413
        SetQTF(String(v));
414
}
415

    
416
RichTextCtrl::RichTextCtrl()
417
{
418
        SetZoom(Zoom(1, 1));
419
        Transparent();
420
        Background(Null);
421
        SetFrame(NullFrame());
422
        AutoHideSb();
423
}
424

    
425
#ifndef PLATFORM_PDA
426

    
427
void Print(Draw& w, const RichText& text, const Rect& page, const Vector<int>& pg)
428
{
429
        LLOG("Print");
430
        int lpage = text.GetHeight(page).page;
431
        PrintPageDraw pw(w);
432
        Size sz = w.GetPageMMs();
433
        Size pgsz = page.Size();
434
        int x = (6000 * sz.cx / 254 - pgsz.cx) / 2;
435
        int y = (6000 * sz.cy / 254 - pgsz.cy) / 2;
436
        for(int pi = 0; pi < pg.GetCount(); pi++) {
437
                int i = pg[pi];
438
                w.StartPage();
439
                w.Offset(x, y);
440
                pw.SetPage(i);
441
                PaintInfo paintinfo;
442
                paintinfo.top = PageY(i, 0);
443
                paintinfo.bottom = PageY(i + 1, 0);
444
                paintinfo.indexentry = Null;
445
                if(text.IsPrintNoLinks())
446
                        paintinfo.hyperlink = Null;
447
                text.Paint(pw, page, paintinfo);
448
                w.End();
449
                String footer = text.GetFooter();
450
                if(!IsNull(footer) && lpage) {
451
                        String n = Format(footer, i + 1, lpage + 1);
452
                        Size nsz = GetTextSize(n, Arial(90).Italic());
453
                        pw.Page(i).DrawText(
454
                                x + pgsz.cx - nsz.cx, y + pgsz.cy + 100,
455
                                n, Arial(90).Italic());
456
                }
457
                w.EndPage();
458
        }
459
}
460

    
461
void Print(Draw& w, const RichText& text, const Rect& page)
462
{
463
        int n = text.GetHeight(page).page;
464
        Vector<int> pg;
465
        for(int i = 0; i <= n; i++)
466
                pg.Add(i);
467
        Print(w, text, page, pg);
468
}
469

    
470
bool Print(const RichText& text, const Rect& page, int currentpage, const char *name)
471
{
472
        PrinterJob pj(name);
473
        pj.CurrentPage(currentpage);
474
        pj.PageCount(text.GetHeight(page).page + 1);
475
        pj.Landscape(page.GetWidth() > page.GetHeight());
476
        if(pj.Execute()) {
477
                Print(pj, text, page, pj.GetPages());
478
                return true;
479
        }
480
        return false;
481
}
482

    
483
#endif
484

    
485
END_UPP_NAMESPACE