~ubuntu-branches/ubuntu/wily/apparmor/wily

« back to all changes in this revision

Viewing changes to deprecated/management/profile-editor/src/wxStyledTextCtrl/CallTip.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-04-27 10:38:07 UTC
  • mfrom: (5.1.118 natty)
  • Revision ID: james.westby@ubuntu.com-20110427103807-ym3rhwys6o84ith0
Tags: 2.6.1-2
debian/copyright: clarify for some full organization names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file CallTip.cxx
 
3
 ** Code for displaying call tips.
 
4
 **/
 
5
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 
6
// The License.txt file describes the conditions under which this software may be distributed.
 
7
 
 
8
#include <stdlib.h>
 
9
#include <string.h>
 
10
 
 
11
#include "Platform.h"
 
12
 
 
13
#include "Scintilla.h"
 
14
#include "CallTip.h"
 
15
 
 
16
CallTip::CallTip() {
 
17
        wCallTip = 0;
 
18
        inCallTipMode = false;
 
19
        posStartCallTip = 0;
 
20
        val = 0;
 
21
        rectUp = PRectangle(0,0,0,0);
 
22
        rectDown = PRectangle(0,0,0,0);
 
23
        lineHeight = 1;
 
24
        startHighlight = 0;
 
25
        endHighlight = 0;
 
26
 
 
27
        colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
 
28
        colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
 
29
        colourSel.desired = ColourDesired(0, 0, 0x80);
 
30
        colourShade.desired = ColourDesired(0, 0, 0);
 
31
        colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
 
32
}
 
33
 
 
34
CallTip::~CallTip() {
 
35
        font.Release();
 
36
        wCallTip.Destroy();
 
37
        delete []val;
 
38
        val = 0;
 
39
}
 
40
 
 
41
const int widthArrow = 14;
 
42
 
 
43
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
 
44
        pal.WantFind(colourBG, want);
 
45
        pal.WantFind(colourUnSel, want);
 
46
        pal.WantFind(colourSel, want);
 
47
        pal.WantFind(colourShade, want);
 
48
        pal.WantFind(colourLight, want);
 
49
}
 
50
 
 
51
static bool IsArrowCharacter(char ch) {
 
52
        return (ch == 0) || (ch == '\001') || (ch == '\002');
 
53
}
 
54
 
 
55
void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
 
56
        int posStart, int posEnd, int ytext, PRectangle rcClient,
 
57
        bool highlight, bool draw) {
 
58
        s += posStart;
 
59
        int len = posEnd - posStart;
 
60
        int maxEnd = 0;
 
61
        int ends[10];
 
62
        for (int i=0;i<len;i++) {
 
63
                if (IsArrowCharacter(s[i])) {
 
64
                        if (i > 0)
 
65
                                ends[maxEnd++] = i;
 
66
                        ends[maxEnd++] = i+1;
 
67
                }
 
68
        }
 
69
        ends[maxEnd++] = len;
 
70
        int startSeg = 0;
 
71
        int xEnd;
 
72
        for (int seg = 0; seg<maxEnd; seg++) {
 
73
                int endSeg = ends[seg];
 
74
                if (endSeg > startSeg) {
 
75
                        if (IsArrowCharacter(s[startSeg])) {
 
76
                                xEnd = x + widthArrow;
 
77
                                offsetMain = xEnd;
 
78
                                rcClient.left = x;
 
79
                                rcClient.right = xEnd;
 
80
                                if (draw) {
 
81
                                        const int halfWidth = widthArrow / 2 - 3;
 
82
                                        const int centreX = x + widthArrow / 2 - 1;
 
83
                                        const int centreY = (rcClient.top + rcClient.bottom) / 2;
 
84
                                        surface->FillRectangle(rcClient, colourBG.allocated);
 
85
                                        PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
 
86
                                        surface->FillRectangle(rcClientInner, colourUnSel.allocated);
 
87
 
 
88
                                        if (s[startSeg] == '\001') {
 
89
                                                // Up arrow
 
90
                                                Point pts[] = {
 
91
                                                Point(centreX - halfWidth, centreY + halfWidth / 2),
 
92
                                                Point(centreX + halfWidth, centreY + halfWidth / 2),
 
93
                                                Point(centreX, centreY - halfWidth + halfWidth / 2),
 
94
                                                };
 
95
                                                surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
 
96
                                                                colourBG.allocated, colourBG.allocated);
 
97
                                        } else {
 
98
                                                // Down arrow
 
99
                                                Point pts[] = {
 
100
                                                Point(centreX - halfWidth, centreY - halfWidth / 2),
 
101
                                                Point(centreX + halfWidth, centreY - halfWidth / 2),
 
102
                                                Point(centreX, centreY + halfWidth - halfWidth / 2),
 
103
                                                };
 
104
                                                surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
 
105
                                                                colourBG.allocated, colourBG.allocated);
 
106
                                        }
 
107
                                }
 
108
                                if (s[startSeg] == '\001') {
 
109
                                        rectUp = rcClient;
 
110
                                } else if (s[startSeg] == '\002') {
 
111
                                        rectDown = rcClient;
 
112
                                }
 
113
                        } else {
 
114
                                xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
 
115
                                if (draw) {
 
116
                                        rcClient.left = x;
 
117
                                        rcClient.right = xEnd;
 
118
                                        surface->DrawTextNoClip(rcClient, font, ytext,
 
119
                                                                                s+startSeg, endSeg - startSeg,
 
120
                                                                                highlight ? colourSel.allocated : colourUnSel.allocated,
 
121
                                                                                colourBG.allocated);
 
122
                                }
 
123
                        }
 
124
                        x = xEnd;
 
125
                        startSeg = endSeg;
 
126
                }
 
127
        }
 
128
}
 
129
 
 
130
int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
 
131
        PRectangle rcClientPos = wCallTip.GetClientPosition();
 
132
        PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
 
133
                                rcClientPos.bottom - rcClientPos.top);
 
134
        PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
 
135
 
 
136
        // To make a nice small call tip window, it is only sized to fit most normal characters without accents
 
137
        int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
 
138
 
 
139
        // For each line...
 
140
        // Draw the definition in three parts: before highlight, highlighted, after highlight
 
141
        int ytext = rcClient.top + ascent + 1;
 
142
        rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
 
143
        char *chunkVal = val;
 
144
        bool moreChunks = true;
 
145
        int maxWidth = 0;
 
146
        while (moreChunks) {
 
147
                char *chunkEnd = strchr(chunkVal, '\n');
 
148
                if (chunkEnd == NULL) {
 
149
                        chunkEnd = chunkVal + strlen(chunkVal);
 
150
                        moreChunks = false;
 
151
                }
 
152
                int chunkOffset = chunkVal - val;
 
153
                int chunkLength = chunkEnd - chunkVal;
 
154
                int chunkEndOffset = chunkOffset + chunkLength;
 
155
                int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
 
156
                thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
 
157
                thisStartHighlight -= chunkOffset;
 
158
                int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
 
159
                thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
 
160
                thisEndHighlight -= chunkOffset;
 
161
                rcClient.top = ytext - ascent - 1;
 
162
 
 
163
                int x = 5;
 
164
 
 
165
                DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
 
166
                        ytext, rcClient, false, draw);
 
167
                DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
 
168
                        ytext, rcClient, true, draw);
 
169
                DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
 
170
                        ytext, rcClient, false, draw);
 
171
 
 
172
                chunkVal = chunkEnd + 1;
 
173
                ytext += lineHeight;
 
174
                rcClient.bottom += lineHeight;
 
175
                maxWidth = Platform::Maximum(maxWidth, x);
 
176
        }
 
177
        return maxWidth;
 
178
}
 
179
 
 
180
void CallTip::PaintCT(Surface *surfaceWindow) {
 
181
        if (!val)
 
182
                return;
 
183
        PRectangle rcClientPos = wCallTip.GetClientPosition();
 
184
        PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
 
185
                                rcClientPos.bottom - rcClientPos.top);
 
186
        PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
 
187
 
 
188
        surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
 
189
 
 
190
        offsetMain = 5;
 
191
        PaintContents(surfaceWindow, true);
 
192
 
 
193
        // Draw a raised border around the edges of the window
 
194
        surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
 
195
        surfaceWindow->PenColour(colourShade.allocated);
 
196
        surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
 
197
        surfaceWindow->LineTo(rcClientSize.right - 1, 0);
 
198
        surfaceWindow->PenColour(colourLight.allocated);
 
199
        surfaceWindow->LineTo(0, 0);
 
200
        surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
 
201
}
 
202
 
 
203
void CallTip::MouseClick(Point pt) {
 
204
        clickPlace = 0;
 
205
        if (rectUp.Contains(pt))
 
206
                clickPlace = 1;
 
207
        if (rectDown.Contains(pt))
 
208
                clickPlace = 2;
 
209
}
 
210
 
 
211
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
 
212
                                 const char *faceName, int size,
 
213
                                 int codePage_, int characterSet, Window &wParent) {
 
214
        clickPlace = 0;
 
215
        if (val)
 
216
                delete []val;
 
217
        val = new char[strlen(defn) + 1];
 
218
        if (!val)
 
219
                return PRectangle();
 
220
        strcpy(val, defn);
 
221
        codePage = codePage_;
 
222
        Surface *surfaceMeasure = Surface::Allocate();
 
223
        if (!surfaceMeasure)
 
224
                return PRectangle();
 
225
        surfaceMeasure->Init(wParent.GetID());
 
226
        surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
 
227
        surfaceMeasure->SetDBCSMode(codePage);
 
228
        startHighlight = 0;
 
229
        endHighlight = 0;
 
230
        inCallTipMode = true;
 
231
        posStartCallTip = pos;
 
232
        int deviceHeight = surfaceMeasure->DeviceHeightFont(size);
 
233
        font.Create(faceName, characterSet, deviceHeight, false, false);
 
234
        // Look for multiple lines in the text
 
235
        // Only support \n here - simply means container must avoid \r!
 
236
        int numLines = 1;
 
237
        const char *newline;
 
238
        const char *look = val;
 
239
        rectUp = PRectangle(0,0,0,0);
 
240
        rectDown = PRectangle(0,0,0,0);
 
241
        offsetMain = 5;
 
242
        int width = PaintContents(surfaceMeasure, false) + 5;
 
243
        while ((newline = strchr(look, '\n')) != NULL) {
 
244
                look = newline + 1;
 
245
                numLines++;
 
246
        }
 
247
        lineHeight = surfaceMeasure->Height(font);
 
248
        // Extra line for border and an empty line at top and bottom
 
249
        int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
 
250
        delete surfaceMeasure;
 
251
        return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
 
252
}
 
253
 
 
254
void CallTip::CallTipCancel() {
 
255
        inCallTipMode = false;
 
256
        if (wCallTip.Created()) {
 
257
                wCallTip.Destroy();
 
258
        }
 
259
}
 
260
 
 
261
void CallTip::SetHighlight(int start, int end) {
 
262
        // Avoid flashing by checking something has really changed
 
263
        if ((start != startHighlight) || (end != endHighlight)) {
 
264
                startHighlight = start;
 
265
                endHighlight = end;
 
266
                if (wCallTip.Created()) {
 
267
                        wCallTip.InvalidateAll();
 
268
                }
 
269
        }
 
270
}