private IFlatFileLayoutDescriptor <DummyStringPairModel> GetTestLayoutDescriptor() { var s = new LayoutDescriptor <DummyStringPairModel>() .AppendField(x => x.id, idLength) .AppendField(x => x.x, field1Length); return(s); }
public void Should_AppendStringTypeConverter_When_StringFieldIsAppended() { var layout = new LayoutDescriptor <PrimitiveTypesModel>() .AppendField(x => x.stringTest, fieldLength); var field = layout.GetOrderedFields().FirstOrDefault(); var expectedType = new StringTypeConverter(); Assert.IsInstanceOfType(field.TypeConverter, expectedType.GetType()); }
public override IFlatFileLayoutDescriptor <DailyTemperature> GetLayout(string fileName) { var dirtyIntTypeConverter = new DirtyIntTypeConverter(); var layout = new LayoutDescriptor <DailyTemperature>() .AppendField(x => x.DayId, 4) .AppendField(x => x.LowTemperature, 6, dirtyIntTypeConverter) // Max Temp .AppendField(x => x.HighTemperature, 6, dirtyIntTypeConverter) // Min Temp .WithSkipDefinition(new WeatherReportSkipDefinitions()); return(layout); }
public override IFlatFileLayoutDescriptor <LeagueScore> GetLayout(string fileName) { var layout = new LayoutDescriptor <LeagueScore>() .AppendIgnoredField(7) // Id .AppendField(x => x.TeamName, 16) .AppendIgnoredField(20) .AppendField(x => x.GoalsFor, 4) .AppendIgnoredField(3) .AppendField(x => x.GoalsAgainst, 6) .WithSkipDefinition(new LeagueStandingsSkipDefinitions()); return(layout); }
internal LayoutDescriptor CreateLayoutDescriptor (ErrorText errorText) { LayoutDescriptor result; if (!textWidthDictionary.TryGetValue (errorText.ErrorMessage, out result)) { Pango.Layout layout = new Pango.Layout (editor.PangoContext); layout.FontDescription = fontDescription; layout.SetText (GetFirstLine (errorText)); int w, h; layout.GetPixelSize (out w, out h); textWidthDictionary[errorText.ErrorMessage] = result = new LayoutDescriptor (layout, w, h); } return result; }
public void Should_TestForSkip_When_TestForSkipObjectIsDefined() { // Arrange var layout = new LayoutDescriptor <DummyStringModel>() .WithSkipDefinition(new DummyRowSkipper()) .AppendField(x => x.Id, 5) .AppendField(x => x.Field1, 15) .AppendField(x => x.Field2, 15) .AppendField(x => x.Field3, 15); var parser = new FixedWidthFileParser <DummyStringModel>(layout, GetFilePath("TestForSkip.dat")); // Act var model = parser.ParseFile(); // Assert CollectionAssert.AreEqual(GetExpectedRows().ToList(), model.ToList()); }
public void Should_SkipIgnoredField_When_AppendIgnoredFieldIsUsed() { // Arrange var layout = new LayoutDescriptor <DummyStringModel>() .AppendField(x => x.Id, 5) .AppendField(x => x.Field1, 15) .AppendField(x => x.Field2, 15) .AppendIgnoredField(30) .AppendField(x => x.Field3, 15); var parser = new FixedWidthFileParser <DummyStringModel>(layout, GetFilePath("SkipColumns.dat")); // Act var model = parser.ParseFile(); // Assert CollectionAssert.AreEqual(GetExpectedRows().ToList(), model.ToList()); }
public void Should_SkipHeaderRow_When_SkipHeaderSettingIsEnabled() { // Arrange var layout = new LayoutDescriptor <DummyStringModel>() .AppendField(x => x.Id, 5) .AppendField(x => x.Field1, 15) .AppendField(x => x.Field2, 15) .AppendField(x => x.Field3, 15) .WithSkipDefinition(new SkipFirstRow()); var parser = new FixedWidthFileParser <DummyStringModel>(layout, GetFilePath("SkipHeaderRow.dat")); // Act var model = parser.ParseFile(); // Assert CollectionAssert.AreEqual(GetExpectedRows().ToList(), model.ToList()); }
public void Should_SkipAllDefinedRows_When_CollectionOfSkipDefinitionsIsUsed() { // Arrange var layout = new LayoutDescriptor <DummyStringModel>() .AppendField(x => x.Id, 5) .AppendField(x => x.Field1, 15) .AppendField(x => x.Field2, 15) .AppendField(x => x.Field3, 15) .WithSkipDefinition(new SkipBlankRows()) .WithSkipDefinition(new SkipFirstRow()); var parser = new FixedWidthFileParser <DummyStringModel>(layout, GetFilePath("SkipMultiple.dat")); // Act var model = parser.ParseFile(); // Assert CollectionAssert.AreEqual(GetExpectedRows().ToList(), model.ToList()); }
public LayoutWrapper CreateLinePartLayout (ISyntaxMode mode, DocumentLine line, int logicalRulerColumn, int offset, int length, int selectionStart, int selectionEnd) { bool containsPreedit = textEditor.ContainsPreedit (offset, length); LayoutDescriptor descriptor; if (!containsPreedit && layoutDict.TryGetValue (line, out descriptor)) { bool isInvalid; if (descriptor.Equals (line, offset, length, selectionStart, selectionEnd, out isInvalid) && descriptor.Layout != null) { return descriptor.Layout; } descriptor.Dispose (); layoutDict.Remove (line); } var wrapper = new LayoutWrapper (PangoUtil.CreateLayout (textEditor)); wrapper.IsUncached = containsPreedit; if (logicalRulerColumn < 0) logicalRulerColumn = line.GetLogicalColumn (textEditor.GetTextEditorData (), textEditor.Options.RulerColumn); var atts = new FastPangoAttrList (); wrapper.Layout.Alignment = Pango.Alignment.Left; wrapper.Layout.FontDescription = textEditor.Options.Font; wrapper.Layout.Tabs = tabArray; if (textEditor.Options.WrapLines) { wrapper.Layout.Wrap = Pango.WrapMode.WordChar; wrapper.Layout.Width = (int)((textEditor.Allocation.Width - XOffset - TextStartPosition) * Pango.Scale.PangoScale); } StringBuilder textBuilder = new StringBuilder (); var chunks = GetCachedChunks (mode, Document, textEditor.ColorStyle, line, offset, length); wrapper.Chunks = chunks; foreach (var chunk in chunks) { try { textBuilder.Append (Document.GetTextAt (chunk)); } catch { Console.WriteLine (chunk); } } int lineOffset = line.Offset; string lineText = textBuilder.ToString (); uint preeditLength = 0; if (containsPreedit) { if (textEditor.GetTextEditorData ().IsCaretInVirtualLocation) { lineText = textEditor.GetTextEditorData ().GetIndentationString (textEditor.Caret.Location) + textEditor.preeditString; } else { lineText = lineText.Insert (textEditor.preeditOffset - offset, textEditor.preeditString); } preeditLength = (uint)textEditor.preeditString.Length; } char[] lineChars = lineText.ToCharArray (); //int startOffset = offset, endOffset = offset + length; uint curIndex = 0, byteIndex = 0; uint curChunkIndex = 0, byteChunkIndex = 0; uint oldEndIndex = 0; foreach (Chunk chunk in chunks) { ChunkStyle chunkStyle = chunk != null ? textEditor.ColorStyle.GetChunkStyle (chunk) : null; foreach (TextLineMarker marker in line.Markers) chunkStyle = marker.GetStyle (chunkStyle); if (chunkStyle != null) { //startOffset = chunk.Offset; //endOffset = chunk.EndOffset; uint startIndex = (uint)(oldEndIndex); uint endIndex = (uint)(startIndex + chunk.Length); oldEndIndex = endIndex; var markers = Document.GetTextSegmentMarkersAt (line).Where (m => m.IsVisible).ToArray (); HandleSelection (lineOffset, logicalRulerColumn, selectionStart, selectionEnd, chunk.Offset, chunk.EndOffset, delegate(int start, int end) { if (containsPreedit) { if (textEditor.preeditOffset < start) start += (int)preeditLength; if (textEditor.preeditOffset < end) end += (int)preeditLength; } var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex); var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex); var color = ColorStyle.GetForeground (chunkStyle); foreach (var marker in markers) { var chunkMarker = marker as IChunkMarker; if (chunkMarker == null) continue; chunkMarker.ChangeForeColor (textEditor, chunk, ref color); } atts.AddForegroundAttribute ((HslColor)color, si, ei); if (!chunkStyle.TransparentBackground && GetPixel (ColorStyle.PlainText.Background) != GetPixel (chunkStyle.Background)) { wrapper.AddBackground (chunkStyle.Background, (int)si, (int)ei); } else if (chunk.SpanStack != null && ColorStyle != null) { foreach (var span in chunk.SpanStack) { if (span == null || string.IsNullOrEmpty (span.Color)) continue; var spanStyle = ColorStyle.GetChunkStyle (span.Color); if (spanStyle != null && !spanStyle.TransparentBackground && GetPixel (ColorStyle.PlainText.Background) != GetPixel (spanStyle.Background)) { wrapper.AddBackground (spanStyle.Background, (int)si, (int)ei); break; } } } }, delegate(int start, int end) { if (containsPreedit) { if (textEditor.preeditOffset < start) start += (int)preeditLength; if (textEditor.preeditOffset < end) end += (int)preeditLength; } var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex); var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex); var color = !SelectionColor.TransparentForeground ? SelectionColor.Foreground : ColorStyle.GetForeground (chunkStyle); foreach (var marker in markers) { var chunkMarker = marker as IChunkMarker; if (chunkMarker == null) continue; chunkMarker.ChangeForeColor (textEditor, chunk, ref color); } atts.AddForegroundAttribute ((HslColor)color, si, ei); if (!wrapper.StartSet) wrapper.SelectionStartIndex = (int)si; wrapper.SelectionEndIndex = (int)ei; }); var translatedStartIndex = TranslateToUTF8Index (lineChars, (uint)startIndex, ref curChunkIndex, ref byteChunkIndex); var translatedEndIndex = TranslateToUTF8Index (lineChars, (uint)endIndex, ref curChunkIndex, ref byteChunkIndex); if (chunkStyle.FontWeight != Xwt.Drawing.FontWeight.Normal) atts.AddWeightAttribute ((Pango.Weight)chunkStyle.FontWeight, translatedStartIndex, translatedEndIndex); if (chunkStyle.FontStyle != Xwt.Drawing.FontStyle.Normal) atts.AddStyleAttribute ((Pango.Style)chunkStyle.FontStyle, translatedStartIndex, translatedEndIndex); if (chunkStyle.Underline) atts.AddUnderlineAttribute (Pango.Underline.Single, translatedStartIndex, translatedEndIndex); } } if (containsPreedit) { var si = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset), ref curIndex, ref byteIndex); var ei = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset + preeditLength), ref curIndex, ref byteIndex); if (textEditor.GetTextEditorData ().IsCaretInVirtualLocation) { uint len = (uint)textEditor.GetTextEditorData ().GetIndentationString (textEditor.Caret.Location).Length; si += len; ei += len; } atts.AddForegroundAttribute ((HslColor)ColorStyle.PlainText.Foreground, si, ei); var hasBackground = wrapper.BackgroundColors.Any (bg => bg.FromIdx <= si && bg.ToIdx >= ei); if (hasBackground) atts.AddBackgroundAttribute ((HslColor)ColorStyle.PlainText.Background, si, ei); atts.InsertOffsetList (textEditor.preeditAttrs, si, ei); } wrapper.LineChars = lineChars; wrapper.Layout.SetText (lineText); wrapper.IndentSize = 0; for (int i = 0; i < lineChars.Length; i++) { char ch = lineChars [i]; if (ch == ' ') { wrapper.IndentSize ++; } else if (ch == '\t') { wrapper.IndentSize = GetNextTabstop (textEditor.GetTextEditorData (), wrapper.IndentSize); } else { break; } } var nextLine = line.NextLine; wrapper.EolSpanStack = nextLine != null ? nextLine.StartSpan : null; atts.AssignTo (wrapper.Layout); atts.Dispose (); int w, h; wrapper.Layout.GetSize (out w, out h); wrapper.PangoWidth = w; selectionStart = System.Math.Max (line.Offset - 1, selectionStart); selectionEnd = System.Math.Min (line.EndOffsetIncludingDelimiter + 1, selectionEnd); descriptor = new LayoutDescriptor (line, offset, length, wrapper, selectionStart, selectionEnd); if (!containsPreedit) layoutDict [line] = descriptor; //textEditor.GetTextEditorData ().HeightTree.SetLineHeight (line.LineNumber, System.Math.Max (LineHeight, System.Math.Floor (h / Pango.Scale.PangoScale))); return wrapper; }
protected override DriverResult Display(ProjectionPart part, string displayType, dynamic shapeHelper) { var query = part.Record.QueryPartRecord; // retrieving paging parameters var queryString = Services.WorkContext.HttpContext.Request.QueryString; var pageKey = String.IsNullOrWhiteSpace(part.Record.PagerSuffix) ? "page" : "page-" + part.Record.PagerSuffix; var page = 0; if (queryString.AllKeys.Contains(pageKey)) { Int32.TryParse(queryString[pageKey], out page); } // default page size int pageSize = part.Record.Items; // if 0, then assume "All" if (pageSize == 0) { pageSize = Int32.MaxValue; } // if pageSize is provided on the query string, ensure it is compatible with allowed limits var pageSizeKey = "pageSize" + part.Record.PagerSuffix; if (queryString.AllKeys.Contains(pageSizeKey)) { int qsPageSize; if (Int32.TryParse(queryString[pageSizeKey], out qsPageSize)) { if (part.Record.MaxItems == 0 || qsPageSize <= part.Record.MaxItems) { pageSize = qsPageSize; } } } var pager = new Pager(Services.WorkContext.CurrentSite, page, pageSize); var pagerShape = shapeHelper.Pager(pager) .ContentPart(part) .PagerId(pageKey); return(Combined( ContentShape("Parts_ProjectionPart_Pager", shape => { if (!part.Record.DisplayPager) { return null; } return pagerShape; }), ContentShape("Parts_ProjectionPart_List", shape => { // generates a link to the RSS feed for this term var metaData = Services.ContentManager.GetItemMetadata(part.ContentItem); _feedManager.Register(metaData.DisplayText, "rss", new RouteValueDictionary { { "projection", part.Id } }); // execute the query var contentItems = _projectionManager.GetContentItems(query.Id, pager.GetStartIndex() + part.Record.Skip, pager.PageSize).ToList(); // sanity check so that content items with ProjectionPart can't be added here, or it will result in an infinite loop contentItems = contentItems.Where(x => !x.Has <ProjectionPart>()).ToList(); // applying layout var layout = part.Record.LayoutRecord; LayoutDescriptor layoutDescriptor = layout == null ? null : _projectionManager.DescribeLayouts().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == layout.Category && x.Type == layout.Type); // create pager shape if (part.Record.DisplayPager) { var contentItemsCount = _projectionManager.GetCount(query.Id); pagerShape.TotalItemCount(contentItemsCount); } // renders in a standard List shape if no specific layout could be found if (layoutDescriptor == null) { var list = Services.New.List(); var contentShapes = contentItems.Select(item => Services.ContentManager.BuildDisplay(item, "Summary")); list.AddRange(contentShapes); return list; } var tokens = new Dictionary <string, object> { { "Content", part.ContentItem } }; var allFielDescriptors = _projectionManager.DescribeProperties().ToList(); var fieldDescriptors = layout.Properties.OrderBy(p => p.Position).Select(p => allFielDescriptors.SelectMany(x => x.Descriptors).Select(d => new { Descriptor = d, Property = p }).FirstOrDefault(x => x.Descriptor.Category == p.Category && x.Descriptor.Type == p.Type)).ToList(); var tokenizedDescriptors = fieldDescriptors.Select(fd => new { fd.Descriptor, fd.Property, State = FormParametersHelper.ToDynamic(_tokenizer.Replace(fd.Property.State, tokens)) }).ToList(); var layoutComponents = contentItems.Select( contentItem => { var contentItemMetadata = Services.ContentManager.GetItemMetadata(contentItem); var propertyDescriptors = tokenizedDescriptors.Select( d => { var fieldContext = new PropertyContext { State = d.State, Tokens = tokens }; return new { d.Property, Shape = d.Descriptor.Property(fieldContext, contentItem) }; }); // apply all settings to the field content, wrapping it in a FieldWrapper shape var properties = Services.New.Properties( Items: propertyDescriptors.Select( pd => Services.New.PropertyWrapper( Item: pd.Shape, Property: pd.Property, ContentItem: contentItem, ContentItemMetadata: contentItemMetadata ) ) ); return new LayoutComponentResult { ContentItem = contentItem, ContentItemMetadata = contentItemMetadata, Properties = properties }; }).ToList(); var tokenizedState = _tokenizer.Replace(layout.State, new Dictionary <string, object> { { "Content", part.ContentItem } }); var renderLayoutContext = new LayoutContext { State = FormParametersHelper.ToDynamic(tokenizedState), LayoutRecord = layout, }; if (layout.GroupProperty != null) { var groupPropertyId = layout.GroupProperty.Id; var display = _displayHelperFactory.CreateHelper(new ViewContext { HttpContext = _workContextAccessor.GetContext().HttpContext }, new ViewDataContainer()); // index by PropertyWrapper shape var groups = layoutComponents.GroupBy( x => { var propertyShape = ((IEnumerable <dynamic>)x.Properties.Items).First(p => ((PropertyRecord)p.Property).Id == groupPropertyId); // clear the wrappers, as they shouldn't be needed to generate the grouping key itself // otherwise the DisplayContext.View is null, and throws an exception if a wrapper is rendered (#18558) ((IShape)propertyShape).Metadata.Wrappers.Clear(); string key = Convert.ToString(display(propertyShape)); return key; }).Select(x => new { Key = x.Key, Components = x }); var list = Services.New.List(); foreach (var group in groups) { var localResult = layoutDescriptor.Render(renderLayoutContext, group.Components); // add the Context to the shape localResult.Context(renderLayoutContext); list.Add(Services.New.LayoutGroup(Key: new MvcHtmlString(group.Key), List: localResult)); } return list; } var layoutResult = layoutDescriptor.Render(renderLayoutContext, layoutComponents); // add the Context to the shape layoutResult.Context(renderLayoutContext); return layoutResult; }))); }
public LayoutWrapper CreateLinePartLayout (ISyntaxMode mode, LineSegment line, int logicalRulerColumn, int offset, int length, int selectionStart, int selectionEnd) { bool containsPreedit = textEditor.ContainsPreedit (offset, length); LayoutDescriptor descriptor; if (!containsPreedit && layoutDict.TryGetValue (line, out descriptor)) { bool isInvalid; if (descriptor.Equals (line, offset, length, selectionStart, selectionEnd, out isInvalid) && descriptor.Layout != null) { return descriptor.Layout; } descriptor.Dispose (); layoutDict.Remove (line); } var wrapper = new LayoutWrapper (PangoUtil.CreateLayout (textEditor)); wrapper.IsUncached = containsPreedit; if (logicalRulerColumn < 0) logicalRulerColumn = line.GetLogicalColumn (textEditor.GetTextEditorData (), textEditor.Options.RulerColumn); var atts = new FastPangoAttrList (); wrapper.Layout.Alignment = Pango.Alignment.Left; wrapper.Layout.FontDescription = textEditor.Options.Font; wrapper.Layout.Tabs = tabArray; StringBuilder textBuilder = new StringBuilder (); var chunks = GetCachedChunks (mode, Document, textEditor.ColorStyle, line, offset, length); foreach (var chunk in chunks) { try { textBuilder.Append (Document.GetTextAt (chunk)); } catch { Console.WriteLine (chunk); } } var spanStack = line.StartSpan; int lineOffset = line.Offset; string lineText = textBuilder.ToString (); uint preeditLength = 0; if (containsPreedit) { lineText = lineText.Insert (textEditor.preeditOffset - offset, textEditor.preeditString); preeditLength = (uint)textEditor.preeditString.Length; } char[] lineChars = lineText.ToCharArray (); //int startOffset = offset, endOffset = offset + length; uint curIndex = 0, byteIndex = 0; uint curChunkIndex = 0, byteChunkIndex = 0; uint oldEndIndex = 0; foreach (Chunk chunk in chunks) { ChunkStyle chunkStyle = chunk != null ? textEditor.ColorStyle.GetChunkStyle (chunk) : null; spanStack = chunk.SpanStack ?? spanStack; foreach (TextMarker marker in line.Markers) chunkStyle = marker.GetStyle (chunkStyle); if (chunkStyle != null) { //startOffset = chunk.Offset; //endOffset = chunk.EndOffset; uint startIndex = (uint)(oldEndIndex); uint endIndex = (uint)(startIndex + chunk.Length); oldEndIndex = endIndex; HandleSelection (lineOffset, logicalRulerColumn, selectionStart, selectionEnd, chunk.Offset, chunk.EndOffset, delegate(int start, int end) { if (containsPreedit) { if (textEditor.preeditOffset < start) start += (int)preeditLength; if (textEditor.preeditOffset < end) end += (int)preeditLength; } var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex); var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex); atts.AddForegroundAttribute (chunkStyle.Color, si, ei); if (!chunkStyle.TransparentBackround && GetPixel (ColorStyle.Default.BackgroundColor) != GetPixel (chunkStyle.BackgroundColor)) { wrapper.AddBackground (chunkStyle.CairoBackgroundColor, (int)si, (int)ei); } else if (chunk.SpanStack != null && ColorStyle != null) { foreach (var span in chunk.SpanStack) { if (span == null) continue; var spanStyle = ColorStyle.GetChunkStyle (span.Color); if (!spanStyle.TransparentBackround && GetPixel (ColorStyle.Default.BackgroundColor) != GetPixel (spanStyle.BackgroundColor)) { wrapper.AddBackground (spanStyle.CairoBackgroundColor, (int)si, (int)ei); break; } } } }, delegate(int start, int end) { if (containsPreedit) { if (textEditor.preeditOffset < start) start += (int)preeditLength; if (textEditor.preeditOffset < end) end += (int)preeditLength; } var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex); var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex); atts.AddForegroundAttribute (SelectionColor.Color, si, ei); if (!wrapper.StartSet) wrapper.SelectionStartIndex = (int)si; wrapper.SelectionEndIndex = (int)ei; }); var translatedStartIndex = TranslateToUTF8Index (lineChars, (uint)startIndex, ref curChunkIndex, ref byteChunkIndex); var translatedEndIndex = TranslateToUTF8Index (lineChars, (uint)endIndex, ref curChunkIndex, ref byteChunkIndex); if (chunkStyle.Bold) atts.AddWeightAttribute (Pango.Weight.Bold, translatedStartIndex, translatedEndIndex); if (chunkStyle.Italic) atts.AddStyleAttribute (Pango.Style.Italic, translatedStartIndex, translatedEndIndex); if (chunkStyle.Underline) atts.AddUnderlineAttribute (Pango.Underline.Single, translatedStartIndex, translatedEndIndex); } } if (containsPreedit) { var si = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset), ref curIndex, ref byteIndex); var ei = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset + preeditLength), ref curIndex, ref byteIndex); atts.Splice (textEditor.preeditAttrs, (int)si, (int)(ei - si)); } wrapper.LineChars = lineChars; wrapper.Layout.SetText (lineText); wrapper.EolSpanStack = spanStack; atts.AssignTo (wrapper.Layout); atts.Dispose (); int w, h; wrapper.Layout.GetSize (out w, out h); wrapper.PangoWidth = w; selectionStart = System.Math.Max (line.Offset - 1, selectionStart); selectionEnd = System.Math.Min (line.EndOffsetIncludingDelimiter + 1, selectionEnd); descriptor = new LayoutDescriptor (line, offset, length, wrapper, selectionStart, selectionEnd); if (!containsPreedit) layoutDict[line] = descriptor; return wrapper; }
LayoutWrapper GetCachedLayout (LineSegment line, int offset, int length, int selectionStart, int selectionEnd, Action<LayoutWrapper> createNew) { bool containsPreedit = offset <= textEditor.preeditOffset && textEditor.preeditOffset <= offset + length; LayoutDescriptor descriptor; if (!containsPreedit && layoutDict.TryGetValue (line, out descriptor)) { bool isInvalid; if (descriptor.Equals (line, offset, length, selectionStart, selectionEnd, out isInvalid)) { return descriptor.Layout; } descriptor.Dispose (); layoutDict.Remove (line); } var wrapper = new LayoutWrapper (PangoUtil.CreateLayout (textEditor)); wrapper.IsUncached = containsPreedit; createNew (wrapper); selectionStart = System.Math.Max (line.Offset - 1, selectionStart); selectionEnd = System.Math.Min (line.EndOffset + 1, selectionEnd); descriptor = new LayoutDescriptor (line, offset, length, wrapper, selectionStart, selectionEnd); if (!containsPreedit) layoutDict[line] = descriptor; return wrapper; }
public bool DrawBackground(TextEditor editor, Cairo.Context g, TextViewMargin.LayoutWrapper layout2, int selectionStart, int selectionEnd, int startOffset, int endOffset, double y, double startXPos, double endXPos, ref bool drawBg) { if (!IsVisible || DebuggingService.IsDebugging) { return(true); } EnsureLayoutCreated(editor); double x = editor.TextViewMargin.XOffset; int right = editor.Allocation.Width; int errorCounterWidth = 0; bool isCaretInLine = startOffset <= editor.Caret.Offset && editor.Caret.Offset <= endOffset; int ew = 0, eh = 0; if (errors.Count > 1 && errorCountLayout != null) { errorCountLayout.GetPixelSize(out ew, out eh); errorCounterWidth = ew + 10; } double x2 = System.Math.Max(right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0) - errorCounterWidth, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); bool isEolSelected = editor.IsSomethingSelected && editor.SelectionMode != SelectionMode.Block ? editor.SelectionRange.Contains(lineSegment.Offset + lineSegment.EditableLength) : false; int active = editor.Document.GetTextAt(lineSegment) == initialText ? 0 : 1; int highlighted = active == 0 && isCaretInLine ? 1 : 0; int selected = 0; double topSize = Math.Floor(editor.LineHeight / 2); double bottomSize = editor.LineHeight / 2 + editor.LineHeight % 2; if (!fitsInSameLine) { if (isEolSelected) { x -= (int)editor.HAdjustment.Value; editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y + editor.LineHeight, editor.TextViewMargin.TextStartPosition, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true); editor.TextViewMargin.DrawRectangleWithRuler(g, x + editor.TextViewMargin.TextStartPosition, new Cairo.Rectangle(x + editor.TextViewMargin.TextStartPosition, y + editor.LineHeight, editor.Allocation.Width + (int)editor.HAdjustment.Value, editor.LineHeight), editor.ColorStyle.Selection.CairoBackgroundColor, true); x += (int)editor.HAdjustment.Value; } else { editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y + editor.LineHeight, x2, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true); } } DrawRectangle(g, x, y, right, topSize); g.Color = colorMatrix [active, TOP, LIGHT, highlighted, selected]; g.Fill(); DrawRectangle(g, x, y + topSize, right, bottomSize); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); g.MoveTo(new Cairo.PointD(x, y + 0.5)); g.LineTo(new Cairo.PointD(x + right, y + 0.5)); g.Color = colorMatrix [active, TOP, LINE, highlighted, selected]; g.Stroke(); g.MoveTo(new Cairo.PointD(x, y + editor.LineHeight - 0.5)); g.LineTo(new Cairo.PointD((fitsInSameLine ? x + right : x2 + 1), y + editor.LineHeight - 0.5)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); } // draw background if (layout2.StartSet || selectionStart == endOffset) { double startX; double endX; if (selectionStart != endOffset) { var start = layout2.Layout.IndexToPos((int)layout2.SelectionStartIndex); startX = (int)(start.X / Pango.Scale.PangoScale); var end = layout2.Layout.IndexToPos((int)layout2.SelectionEndIndex); endX = (int)(end.X / Pango.Scale.PangoScale); } else { startX = x2; endX = startX; } if (editor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX) { endX = startX + 2; } startX += startXPos; endX += startXPos; startX = Math.Max(editor.TextViewMargin.XOffset, startX); // clip region to textviewmargin start if (isEolSelected) { endX = editor.Allocation.Width + (int)editor.HAdjustment.Value; } if (startX < endX) { DrawRectangle(g, startX, y, endX - startX, topSize); g.Color = colorMatrix [active, TOP, LIGHT, highlighted, 1]; g.Fill(); DrawRectangle(g, startX, y + topSize, endX - startX, bottomSize); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, 1]; g.Fill(); g.MoveTo(new Cairo.PointD(startX, y + 0.5)); g.LineTo(new Cairo.PointD(endX, y + 0.5)); g.Color = colorMatrix [active, TOP, LINE, highlighted, 1]; g.Stroke(); if (startX < x2) { g.MoveTo(new Cairo.PointD(startX, y + editor.LineHeight - 0.5)); g.LineTo(new Cairo.PointD(System.Math.Min(endX, x2 + 1), y + editor.LineHeight - 0.5)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, 1]; g.Stroke(); if (x2 + 1 < endX) { g.MoveTo(new Cairo.PointD(x2 + 1, y + editor.LineHeight - 0.5)); g.LineTo(new Cairo.PointD(endX, y + editor.LineHeight - 0.5)); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, 1]; g.Stroke(); } } if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, 1]; g.Stroke(); } } } if (!fitsInSameLine) { y += editor.LineHeight; } double y2 = y + 0.5; double y2Bottom = y2 + editor.LineHeight - 1; selected = isEolSelected && (CollapseExtendedErrors || errors.Count == 1) ? 1 : 0; // draw message text background if (CollapseExtendedErrors || errors.Count == 1) { if (!fitsInSameLine) { // draw box below line g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2 - 1)); g.ClosePath(); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); } else { // draw 'arrow marker' in the same line g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); double mid = y2 + topSize; g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, mid)); g.LineTo(new Cairo.PointD(right, mid)); g.LineTo(new Cairo.PointD(right, y2)); g.ClosePath(); g.Color = colorMatrix [active, TOP, DARK, highlighted, selected]; g.Fill(); g.MoveTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, mid)); g.LineTo(new Cairo.PointD(right, mid)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.ClosePath(); g.Color = colorMatrix [active, BOTTOM, DARK, highlighted, selected]; g.Fill(); // draw border g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2)); g.ClosePath(); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); } } else { if (!fitsInSameLine) { // draw box below line g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2 - 1)); g.ClosePath(); } else { // draw filled arrow box g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2)); g.ClosePath(); } g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); // draw light bottom line g.MoveTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.Stroke(); // stroke left line if (fitsInSameLine) { g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); } else { g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom + 1)); } g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); // stroke top line if (fitsInSameLine) { g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.MoveTo(new Cairo.PointD(right, y2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2)); g.Stroke(); } } if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo(new Cairo.PointD(divider + 0.5, y2)); g.LineTo(new Cairo.PointD(divider + 0.5, y2Bottom)); g.Color = colorMatrix [active, BOTTOM, DARK, highlighted, selected]; g.Stroke(); } } if (errors.Count > 1 && errorCountLayout != null) { double rX = x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth; double rY = y + editor.LineHeight / 6; double rW = errorCounterWidth - 2; double rH = editor.LineHeight * 3 / 4; BookmarkMarker.DrawRoundRectangle(g, rX, rY, 8, rW, rH); g.Color = oldIsOver ? new Cairo.Color(0.3, 0.3, 0.3) : new Cairo.Color(0.5, 0.5, 0.5); g.Fill(); if (CollapseExtendedErrors) { g.Color = gcLight; g.Save(); g.Translate(x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth + 4, y + (editor.LineHeight - eh) / 2 + eh % 2); g.ShowLayout(errorCountLayout); g.Restore(); } else { g.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4); g.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4); g.LineTo(rX + rW / 2, rY + rH / 4); g.ClosePath(); g.Color = new Cairo.Color(1, 1, 1); g.Fill(); } } for (int i = 0; i < layouts.Count; i++) { LayoutDescriptor layout = layouts [i]; x2 = right - layout.Width - border - errorPixbuf.Width; if (i == 0) { x2 -= errorCounterWidth; } x2 = System.Math.Max(x2, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); if (i > 0) { editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y, right, editor.LineHeight), isEolSelected ? editor.ColorStyle.Selection.CairoBackgroundColor : editor.ColorStyle.Default.CairoBackgroundColor, true); g.MoveTo(new Cairo.PointD(x2 + 0.5, y)); g.LineTo(new Cairo.PointD(x2 + 0.5, y + editor.LineHeight)); g.LineTo(new Cairo.PointD(right, y + editor.LineHeight)); g.LineTo(new Cairo.PointD(right, y)); g.ClosePath(); if (CollapseExtendedErrors) { using (var pat = new Cairo.LinearGradient(x2, y, x2, y + editor.LineHeight)) { pat.AddColorStop(0, colorMatrix [active, TOP, LIGHT, highlighted, selected]); pat.AddColorStop(1, colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]); g.Pattern = pat; } } else { g.Color = colorMatrix[active, TOP, LIGHT, highlighted, selected]; } g.Fill(); if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Stroke(); } } } int lw, lh; layout.Layout.GetPixelSize(out lw, out lh); g.Color = (HslColor)(selected == 0 ? gc : gcSelected); g.Save(); g.Translate(x2 + errorPixbuf.Width + border, y + (editor.LineHeight - layout.Height) / 2 + layout.Height % 2); g.ShowLayout(layout.Layout); g.Restore(); y += editor.LineHeight; if (!UseVirtualLines) { break; } } return(true); }
public void Draw(TextEditor editor, Cairo.Context g, int lineNr, Cairo.Rectangle lineArea) { EnsureLayoutCreated(editor); int lineNumber = editor.Document.OffsetToLineNumber(lineSegment.Offset); int errorNumber = lineNr - lineNumber; double x = editor.TextViewMargin.XOffset; double y = lineArea.Y; double right = editor.Allocation.Width; int errorCounterWidth = 0; int ew = 0, eh = 0; if (errors.Count > 1 && errorCountLayout != null) { errorCountLayout.GetPixelSize(out ew, out eh); errorCounterWidth = ew + 10; } double x2 = System.Math.Max(right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0) - errorCounterWidth, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); // bool isEolSelected = editor.IsSomethingSelected && editor.SelectionMode != SelectionMode.Block ? editor.SelectionRange.Contains (lineSegment.Offset + lineSegment.EditableLength) : false; int active = editor.Document.GetTextAt(lineSegment) == initialText ? 0 : 1; bool isCaretInLine = lineSegment.Offset <= editor.Caret.Offset && editor.Caret.Offset <= lineSegment.EndOffset; int highlighted = active == 0 && isCaretInLine ? 1 : 0; int selected = 0; LayoutDescriptor layout = layouts[errorNumber]; x2 = right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0); x2 -= errorCounterWidth; x2 = System.Math.Max(x2, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); g.MoveTo(new Cairo.PointD(x2 + 0.5, y)); g.LineTo(new Cairo.PointD(x2 + 0.5, y + editor.LineHeight)); g.LineTo(new Cairo.PointD(right, y + editor.LineHeight)); g.LineTo(new Cairo.PointD(right, y)); g.ClosePath(); g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.MoveTo(new Cairo.PointD(x2 + 0.5, y)); g.LineTo(new Cairo.PointD(x2 + 0.5, y + editor.LineHeight)); if (errorNumber == errors.Count - 1) { g.LineTo(new Cairo.PointD(lineArea.X + lineArea.Width, y + editor.LineHeight)); } g.Stroke(); if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Stroke(); } } g.Save(); g.Translate(x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border, y + (editor.LineHeight - layout.Height) / 2 + layout.Height % 2); g.Color = selected == 0 ? gc : gcSelected; g.ShowLayout(layout.Layout); g.Restore(); // if (ShowIconsInBubble) // win.DrawPixbuf (editor.Style.BaseGC (Gtk.StateType.Normal), errors[errorNumber].IsError ? errorPixbuf : warningPixbuf, 0, 0, x2, y + (editor.LineHeight - errorPixbuf.Height) / 2, errorPixbuf.Width, errorPixbuf.Height, Gdk.RgbDither.None, 0, 0); }