Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
421c5b0e
Commit
421c5b0e
authored
Aug 12, 2008
by
Dylan Smith
Committed by
Alexandre Julliard
Aug 18, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
richedit: Borders are now drawn for tables and nested tables.
parent
967c148a
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
146 additions
and
3 deletions
+146
-3
editor.c
dlls/riched20/editor.c
+53
-0
editstr.h
dlls/riched20/editstr.h
+15
-0
paint.c
dlls/riched20/paint.c
+0
-0
reader.c
dlls/riched20/reader.c
+1
-0
rtf.h
dlls/riched20/rtf.h
+43
-0
table.c
dlls/riched20/table.c
+1
-0
wrap.c
dlls/riched20/wrap.c
+33
-3
No files found.
dlls/riched20/editor.c
View file @
421c5b0e
...
@@ -451,6 +451,10 @@ static void ME_RTFParAttrHook(RTF_Info *info)
...
@@ -451,6 +451,10 @@ static void ME_RTFParAttrHook(RTF_Info *info)
switch
(
info
->
rtfMinor
)
switch
(
info
->
rtfMinor
)
{
{
case
rtfParDef
:
/* restores default paragraph attributes */
case
rtfParDef
:
/* restores default paragraph attributes */
if
(
!
info
->
editor
->
bEmulateVersion10
)
/* v4.1 */
info
->
borderType
=
RTFBorderParaLeft
;
else
/* v1.0 - 3.0 */
info
->
borderType
=
RTFBorderParaTop
;
fmt
.
dwMask
=
PFM_ALIGNMENT
|
PFM_BORDER
|
PFM_LINESPACING
|
PFM_TABSTOPS
|
fmt
.
dwMask
=
PFM_ALIGNMENT
|
PFM_BORDER
|
PFM_LINESPACING
|
PFM_TABSTOPS
|
PFM_OFFSET
|
PFM_RIGHTINDENT
|
PFM_SPACEAFTER
|
PFM_SPACEBEFORE
|
PFM_OFFSET
|
PFM_RIGHTINDENT
|
PFM_SPACEAFTER
|
PFM_SPACEBEFORE
|
PFM_STARTINDENT
;
PFM_STARTINDENT
;
...
@@ -656,6 +660,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
...
@@ -656,6 +660,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt
.
wNumberingStart
=
info
->
rtfParam
;
fmt
.
wNumberingStart
=
info
->
rtfParam
;
break
;
break
;
case
rtfBorderLeft
:
case
rtfBorderLeft
:
info
->
borderType
=
RTFBorderParaLeft
;
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
{
{
...
@@ -667,6 +672,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
...
@@ -667,6 +672,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt
.
dwMask
=
PFM_BORDER
;
fmt
.
dwMask
=
PFM_BORDER
;
break
;
break
;
case
rtfBorderRight
:
case
rtfBorderRight
:
info
->
borderType
=
RTFBorderParaRight
;
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
{
{
...
@@ -678,6 +684,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
...
@@ -678,6 +684,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt
.
dwMask
=
PFM_BORDER
;
fmt
.
dwMask
=
PFM_BORDER
;
break
;
break
;
case
rtfBorderTop
:
case
rtfBorderTop
:
info
->
borderType
=
RTFBorderParaTop
;
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
{
{
...
@@ -689,6 +696,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
...
@@ -689,6 +696,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt
.
dwMask
=
PFM_BORDER
;
fmt
.
dwMask
=
PFM_BORDER
;
break
;
break
;
case
rtfBorderBottom
:
case
rtfBorderBottom
:
info
->
borderType
=
RTFBorderParaBottom
;
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
if
(
!
(
fmt
.
dwMask
&
PFM_BORDER
))
{
{
...
@@ -735,11 +743,24 @@ static void ME_RTFParAttrHook(RTF_Info *info)
...
@@ -735,11 +743,24 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt
.
dwMask
=
PFM_BORDER
;
fmt
.
dwMask
=
PFM_BORDER
;
break
;
break
;
case
rtfBorderWidth
:
case
rtfBorderWidth
:
{
int
borderSide
=
info
->
borderType
&
RTFBorderSideMask
;
RTFTable
*
tableDef
=
info
->
tableDef
;
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
/* we assume that borders have been created before (RTF spec) */
/* we assume that borders have been created before (RTF spec) */
fmt
.
wBorderWidth
|=
((
info
->
rtfParam
/
15
)
&
7
)
<<
8
;
fmt
.
wBorderWidth
|=
((
info
->
rtfParam
/
15
)
&
7
)
<<
8
;
if
((
info
->
borderType
&
RTFBorderTypeMask
)
==
RTFBorderTypeCell
)
{
RTFBorder
*
border
;
if
(
!
tableDef
||
tableDef
->
numCellsDefined
>=
MAX_TABLE_CELLS
)
break
;
border
=
&
tableDef
->
cells
[
tableDef
->
numCellsDefined
].
border
[
borderSide
];
border
->
width
=
info
->
rtfParam
;
break
;
}
fmt
.
dwMask
=
PFM_BORDER
;
fmt
.
dwMask
=
PFM_BORDER
;
break
;
break
;
}
case
rtfBorderSpace
:
case
rtfBorderSpace
:
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
ME_GetSelectionParaFormat
(
info
->
editor
,
&
fmt
);
/* we assume that borders have been created before (RTF spec) */
/* we assume that borders have been created before (RTF spec) */
...
@@ -760,6 +781,10 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
...
@@ -760,6 +781,10 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
{
{
case
rtfRowDef
:
case
rtfRowDef
:
{
{
if
(
!
info
->
editor
->
bEmulateVersion10
)
/* v4.1 */
info
->
borderType
=
0
;
/* Not sure */
else
/* v1.0 - 3.0 */
info
->
borderType
=
RTFBorderRowTop
;
if
(
!
info
->
tableDef
)
{
if
(
!
info
->
tableDef
)
{
info
->
tableDef
=
ME_MakeTableDef
(
info
->
editor
);
info
->
tableDef
=
ME_MakeTableDef
(
info
->
editor
);
}
else
{
}
else
{
...
@@ -786,6 +811,30 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
...
@@ -786,6 +811,30 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
}
}
info
->
tableDef
->
numCellsDefined
++
;
info
->
tableDef
->
numCellsDefined
++
;
break
;
break
;
case
rtfRowBordTop
:
info
->
borderType
=
RTFBorderRowTop
;
break
;
case
rtfRowBordLeft
:
info
->
borderType
=
RTFBorderRowLeft
;
break
;
case
rtfRowBordBottom
:
info
->
borderType
=
RTFBorderRowBottom
;
break
;
case
rtfRowBordRight
:
info
->
borderType
=
RTFBorderRowRight
;
break
;
case
rtfCellBordTop
:
info
->
borderType
=
RTFBorderCellTop
;
break
;
case
rtfCellBordLeft
:
info
->
borderType
=
RTFBorderCellLeft
;
break
;
case
rtfCellBordBottom
:
info
->
borderType
=
RTFBorderCellBottom
;
break
;
case
rtfCellBordRight
:
info
->
borderType
=
RTFBorderCellRight
;
break
;
case
rtfRowGapH
:
case
rtfRowGapH
:
if
(
info
->
tableDef
)
if
(
info
->
tableDef
)
info
->
tableDef
->
gapH
=
info
->
rtfParam
;
info
->
tableDef
->
gapH
=
info
->
rtfParam
;
...
@@ -882,6 +931,10 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
...
@@ -882,6 +931,10 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
for
(
i
=
0
;
i
<
tableDef
->
numCellsDefined
;
i
++
)
for
(
i
=
0
;
i
<
tableDef
->
numCellsDefined
;
i
++
)
{
{
cell
->
member
.
cell
.
nRightBoundary
=
tableDef
->
cells
[
i
].
rightBoundary
;
cell
->
member
.
cell
.
nRightBoundary
=
tableDef
->
cells
[
i
].
rightBoundary
;
cell
->
member
.
cell
.
border
.
top
.
width
=
tableDef
->
cells
[
i
].
border
[
0
].
width
;
cell
->
member
.
cell
.
border
.
left
.
width
=
tableDef
->
cells
[
i
].
border
[
1
].
width
;
cell
->
member
.
cell
.
border
.
bottom
.
width
=
tableDef
->
cells
[
i
].
border
[
2
].
width
;
cell
->
member
.
cell
.
border
.
right
.
width
=
tableDef
->
cells
[
i
].
border
[
3
].
width
;
cell
=
cell
->
member
.
cell
.
next_cell
;
cell
=
cell
->
member
.
cell
.
next_cell
;
if
(
!
cell
)
if
(
!
cell
)
{
{
...
...
dlls/riched20/editstr.h
View file @
421c5b0e
...
@@ -165,6 +165,19 @@ typedef struct tagME_Document {
...
@@ -165,6 +165,19 @@ typedef struct tagME_Document {
int
last_wrapped_line
;
int
last_wrapped_line
;
}
ME_Document
;
}
ME_Document
;
typedef
struct
tagME_Border
{
int
width
;
}
ME_Border
;
typedef
struct
tagME_BorderRect
{
ME_Border
top
;
ME_Border
left
;
ME_Border
bottom
;
ME_Border
right
;
}
ME_BorderRect
;
typedef
struct
tagME_Paragraph
typedef
struct
tagME_Paragraph
{
{
PARAFORMAT2
*
pFmt
;
PARAFORMAT2
*
pFmt
;
...
@@ -184,8 +197,10 @@ typedef struct tagME_Cell /* v4.1 */
...
@@ -184,8 +197,10 @@ typedef struct tagME_Cell /* v4.1 */
{
{
int
nNestingLevel
;
/* 0 for normal cells, and greater for nested cells */
int
nNestingLevel
;
/* 0 for normal cells, and greater for nested cells */
int
nRightBoundary
;
int
nRightBoundary
;
ME_BorderRect
border
;
POINT
pt
;
POINT
pt
;
int
nHeight
,
nWidth
;
int
nHeight
,
nWidth
;
int
yTextOffset
;
/* The text offset is caused by the largest top border. */
struct
tagME_DisplayItem
*
prev_cell
,
*
next_cell
,
*
parent_cell
;
struct
tagME_DisplayItem
*
prev_cell
,
*
next_cell
,
*
parent_cell
;
}
ME_Cell
;
}
ME_Cell
;
...
...
dlls/riched20/paint.c
View file @
421c5b0e
This diff is collapsed.
Click to expand it.
dlls/riched20/reader.c
View file @
421c5b0e
...
@@ -247,6 +247,7 @@ void RTFInit(RTF_Info *info)
...
@@ -247,6 +247,7 @@ void RTFInit(RTF_Info *info)
info
->
tableDef
=
NULL
;
info
->
tableDef
=
NULL
;
info
->
nestingLevel
=
0
;
info
->
nestingLevel
=
0
;
info
->
canInheritInTbl
=
FALSE
;
info
->
canInheritInTbl
=
FALSE
;
info
->
borderType
=
0
;
}
}
/*
/*
...
...
dlls/riched20/rtf.h
View file @
421c5b0e
...
@@ -950,6 +950,7 @@ typedef struct RTFFont RTFFont;
...
@@ -950,6 +950,7 @@ typedef struct RTFFont RTFFont;
typedef
struct
RTFColor
RTFColor
;
typedef
struct
RTFColor
RTFColor
;
typedef
struct
RTFStyle
RTFStyle
;
typedef
struct
RTFStyle
RTFStyle
;
typedef
struct
RTFStyleElt
RTFStyleElt
;
typedef
struct
RTFStyleElt
RTFStyleElt
;
typedef
struct
RTFBorder
RTFBorder
;
typedef
struct
RTFCell
RTFCell
;
typedef
struct
RTFCell
RTFCell
;
typedef
struct
RTFTable
RTFTable
;
typedef
struct
RTFTable
RTFTable
;
...
@@ -1006,10 +1007,15 @@ struct RTFStyleElt
...
@@ -1006,10 +1007,15 @@ struct RTFStyleElt
RTFStyleElt
*
rtfNextSE
;
/* next element in style */
RTFStyleElt
*
rtfNextSE
;
/* next element in style */
};
};
struct
RTFBorder
{
int
width
;
};
struct
RTFCell
struct
RTFCell
{
{
int
rightBoundary
;
int
rightBoundary
;
RTFBorder
border
[
4
];
};
};
...
@@ -1019,6 +1025,8 @@ struct RTFTable
...
@@ -1019,6 +1025,8 @@ struct RTFTable
int
numCellsDefined
;
int
numCellsDefined
;
int
gapH
,
leftEdge
;
int
gapH
,
leftEdge
;
/* borders for the table row */
RTFBorder
border
[
6
];
/* Used in v1.0 - v3.0 */
/* Used in v1.0 - v3.0 */
int
numCellsInserted
;
int
numCellsInserted
;
...
@@ -1033,6 +1041,40 @@ struct RTFTable
...
@@ -1033,6 +1041,40 @@ struct RTFTable
RTFTable
*
parent
;
RTFTable
*
parent
;
};
};
# define RTFBorderTypeNone 0x00
# define RTFBorderTypePara 0x10
/* for \brdrX control words */
# define RTFBorderTypeRow 0x20
/* for \trbrdrX control words */
# define RTFBorderTypeCell 0x30
/* for \clbrdrX control words */
# define RTFBorderTypeMask 0xf0
/* The X in the control words \brdrX \trbrdrX and \clbrdrX mentioned above
* should be one of t, l, b, r which stand for top, left, bottom, right
* respectively. */
# define RTFBorderSideTop 0x00
# define RTFBorderSideLeft 0x01
# define RTFBorderSideBottom 0x02
# define RTFBorderSideRight 0x03
# define RTFBorderSideHorizontal 0x04
# define RTFBorderSideVertical 0x05
# define RTFBorderSideMask 0x0f
/* Here are the values from the border types and sides put together. */
# define RTFBorderParaTop 0x10
# define RTFBorderParaLeft 0x11
# define RTFBorderParaBottom 0x12
# define RTFBorderParaRight 0x13
# define RTFBorderRowTop 0x20
# define RTFBorderRowLeft 0x21
# define RTFBorderRowBottom 0x22
# define RTFBorderRowRight 0x23
# define RTFBorderRowHorizontal 0x24
# define RTFBorderRowVertical 0x25
# define RTFBorderCellTop 0x30
# define RTFBorderCellLeft 0x31
# define RTFBorderCellBottom 0x32
# define RTFBorderCellRight 0x33
/*
/*
* Return pointer to new element of type t, or NULL
* Return pointer to new element of type t, or NULL
* if no memory available.
* if no memory available.
...
@@ -1141,6 +1183,7 @@ struct _RTF_Info {
...
@@ -1141,6 +1183,7 @@ struct _RTF_Info {
RTFTable
*
tableDef
;
RTFTable
*
tableDef
;
int
nestingLevel
;
int
nestingLevel
;
BOOL
canInheritInTbl
;
BOOL
canInheritInTbl
;
int
borderType
;
/* value corresponds to the RTFBorder constants. */
};
};
...
...
dlls/riched20/table.c
View file @
421c5b0e
...
@@ -608,6 +608,7 @@ struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor)
...
@@ -608,6 +608,7 @@ struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor)
void
ME_InitTableDef
(
ME_TextEditor
*
editor
,
struct
RTFTable
*
tableDef
)
void
ME_InitTableDef
(
ME_TextEditor
*
editor
,
struct
RTFTable
*
tableDef
)
{
{
ZeroMemory
(
tableDef
->
cells
,
sizeof
(
tableDef
->
cells
));
ZeroMemory
(
tableDef
->
cells
,
sizeof
(
tableDef
->
cells
));
ZeroMemory
(
tableDef
->
border
,
sizeof
(
tableDef
->
border
));
tableDef
->
numCellsDefined
=
0
;
tableDef
->
numCellsDefined
=
0
;
tableDef
->
leftEdge
=
0
;
tableDef
->
leftEdge
=
0
;
if
(
!
editor
->
bEmulateVersion10
)
/* v4.1 */
if
(
!
editor
->
bEmulateVersion10
)
/* v4.1 */
...
...
dlls/riched20/wrap.c
View file @
421c5b0e
...
@@ -606,8 +606,24 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
...
@@ -606,8 +606,24 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
{
{
ME_DisplayItem
*
cell
=
ME_FindItemFwd
(
item
,
diCell
);
ME_DisplayItem
*
cell
=
ME_FindItemFwd
(
item
,
diCell
);
ME_DisplayItem
*
endRowPara
;
ME_DisplayItem
*
endRowPara
;
int
borderWidth
=
0
;
cell
->
member
.
cell
.
pt
=
c
.
pt
;
cell
->
member
.
cell
.
pt
=
c
.
pt
;
endRowPara
=
ME_GetTableRowEnd
(
item
);
/* Offset the text by the largest top border width. */
while
(
cell
->
member
.
cell
.
next_cell
)
{
borderWidth
=
max
(
borderWidth
,
cell
->
member
.
cell
.
border
.
top
.
width
);
cell
=
cell
->
member
.
cell
.
next_cell
;
}
endRowPara
=
ME_FindItemFwd
(
cell
,
diParagraph
);
assert
(
endRowPara
->
member
.
para
.
nFlags
&
MEPF_ROWEND
);
if
(
borderWidth
>
0
)
{
borderWidth
=
max
(
ME_twips2pointsY
(
&
c
,
borderWidth
),
1
);
while
(
cell
)
{
cell
->
member
.
cell
.
yTextOffset
=
borderWidth
;
cell
=
cell
->
member
.
cell
.
prev_cell
;
}
c
.
pt
.
y
+=
borderWidth
;
}
if
(
endRowPara
->
member
.
para
.
pFmt
->
dxStartIndent
>
0
)
if
(
endRowPara
->
member
.
para
.
pFmt
->
dxStartIndent
>
0
)
{
{
int
dxStartIndent
=
endRowPara
->
member
.
para
.
pFmt
->
dxStartIndent
;
int
dxStartIndent
=
endRowPara
->
member
.
para
.
pFmt
->
dxStartIndent
;
...
@@ -620,13 +636,26 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
...
@@ -620,13 +636,26 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
{
{
/* Set all the cells to the height of the largest cell */
/* Set all the cells to the height of the largest cell */
ME_DisplayItem
*
startRowPara
;
ME_DisplayItem
*
startRowPara
;
int
prevHeight
,
nHeight
;
int
prevHeight
,
nHeight
,
bottomBorder
=
0
;
ME_DisplayItem
*
cell
=
ME_FindItemBack
(
item
,
diCell
);
ME_DisplayItem
*
cell
=
ME_FindItemBack
(
item
,
diCell
);
if
(
!
(
item
->
member
.
para
.
next_para
->
member
.
para
.
nFlags
&
MEPF_ROWSTART
))
{
/* Last row, the bottom border is added to the height. */
cell
=
cell
->
member
.
cell
.
prev_cell
;
while
(
cell
)
{
bottomBorder
=
max
(
bottomBorder
,
cell
->
member
.
cell
.
border
.
bottom
.
width
);
cell
=
cell
->
member
.
cell
.
prev_cell
;
}
bottomBorder
=
ME_twips2pointsY
(
&
c
,
bottomBorder
);
cell
=
ME_FindItemBack
(
item
,
diCell
);
}
prevHeight
=
cell
->
member
.
cell
.
nHeight
;
prevHeight
=
cell
->
member
.
cell
.
nHeight
;
nHeight
=
cell
->
member
.
cell
.
prev_cell
->
member
.
cell
.
nHeight
;
nHeight
=
cell
->
member
.
cell
.
prev_cell
->
member
.
cell
.
nHeight
+
bottomBorder
;
cell
->
member
.
cell
.
nHeight
=
nHeight
;
cell
->
member
.
cell
.
nHeight
=
nHeight
;
item
->
member
.
para
.
nHeight
=
nHeight
;
item
->
member
.
para
.
nHeight
=
nHeight
;
cell
=
cell
->
member
.
cell
.
prev_cell
;
cell
=
cell
->
member
.
cell
.
prev_cell
;
cell
->
member
.
cell
.
nHeight
=
nHeight
;
while
(
cell
->
member
.
cell
.
prev_cell
)
while
(
cell
->
member
.
cell
.
prev_cell
)
{
{
cell
=
cell
->
member
.
cell
.
prev_cell
;
cell
=
cell
->
member
.
cell
.
prev_cell
;
...
@@ -664,6 +693,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
...
@@ -664,6 +693,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
c
.
pt
.
x
=
cell
->
pt
.
x
+
cell
->
nWidth
;
c
.
pt
.
x
=
cell
->
pt
.
x
+
cell
->
nWidth
;
c
.
pt
.
y
=
cell
->
pt
.
y
;
c
.
pt
.
y
=
cell
->
pt
.
y
;
cell
->
next_cell
->
member
.
cell
.
pt
=
c
.
pt
;
cell
->
next_cell
->
member
.
cell
.
pt
=
c
.
pt
;
c
.
pt
.
y
+=
cell
->
yTextOffset
;
}
}
else
else
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment