1+ import * as vscode from 'vscode' ;
2+ import { TemplateColumn , TemplateDocument , TemplateMergeCells , TemplateRow } from './templatInterfaces' ;
3+
4+ export class TemplatePanel {
5+
6+ public static readonly viewType = 'metadataViewer.templatePanel' ;
7+
8+ public static show ( extensionUri : vscode . Uri , document : TemplateDocument ) {
9+ const column = vscode . window . activeTextEditor
10+ ? vscode . window . activeTextEditor . viewColumn
11+ : undefined ;
12+
13+ const panel = vscode . window . createWebviewPanel (
14+ TemplatePanel . viewType ,
15+ "Макет" ,
16+ column || vscode . ViewColumn . One
17+ ) ;
18+
19+ panel . webview . html = this . _getHtmlForWebview ( panel . webview , extensionUri , document ) ;
20+ }
21+
22+ private static _getHtmlForWebview ( webview : vscode . Webview , extensionUri : vscode . Uri , document : TemplateDocument ) {
23+ const styleUri = webview . asWebviewUri ( vscode . Uri . joinPath ( extensionUri , 'media' , 'template' , 'styles.css' ) ) ;
24+ let indexRow = 0 ;
25+ let hasColumndId = false ;
26+ document . columns . forEach ( columns => {
27+ if ( columns . id ) {
28+ hasColumndId = true ;
29+ }
30+ } ) ;
31+
32+ return `<!DOCTYPE html>
33+ <html lang="en">
34+ <head>
35+ <meta charset="UTF-8">
36+
37+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
38+ <title></title>
39+
40+ <link href="${ styleUri } " rel="stylesheet" />
41+ </style>
42+ </head>
43+ <body>
44+ ${ document . columns
45+ . filter ( columns => columns . size [ 0 ] !== '0' )
46+ . map ( columns => { return `
47+ <table style="width: 800px; max-width: 800px; table-layout: fixed; white-space: nowrap; border-color: #333;" rules="all">
48+ <thead>
49+ <tr>
50+ <th style="max-width: 30px; width: 30px;"></th>
51+ ${ ( columns
52+ . columnsItem ?? [ ] )
53+ . map ( ( c , index ) => {
54+ const formatIndex = Number ( c . column [ 0 ] . formatIndex [ 0 ] ) - 1 ;
55+ const columnWidth = document . format [ formatIndex ] . width ? document . format [ formatIndex ] . width [ 0 ] : '80' ;
56+
57+ return '<th' + ( document . format [ formatIndex ] ?
58+ ` style="max-width: ${ columnWidth } px; width: ${ columnWidth } px;"` :
59+ '' ) + `>${ index + 1 } </th>` ;
60+ } ) . join ( '' ) }
61+ </tr>
62+ </thead>
63+ ${ ( ( ) => {
64+ return document . rowsItem
65+ . filter ( ri => hasColumndId ? ( ri . row [ 0 ] . columnsID ? ri . row [ 0 ] . columnsID [ 0 ] === columns . id [ 0 ] : false ) : true )
66+ . map ( ( _ ) => {
67+ let additionalRows = '' ;
68+ for ( let i = indexRow ; i < Number ( _ . index ) - 1 ; i ++ ) {
69+ // TODO: Высота из формата
70+ additionalRows += `<tr style="height: 20px;"><td style="text-align: center;">${ ++ indexRow + 1 } </td></tr>` ;
71+ indexRow ++ ;
72+ }
73+ indexRow = Number ( _ . index ) ;
74+ return additionalRows + _getRow ( _ , document ) ;
75+ } ) . join ( '' ) ;
76+ } ) ( ) }
77+ </table>` ;
78+ } )
79+ }
80+ </body>
81+ </html>` ;
82+ }
83+ }
84+
85+ function _getRow ( templateRow : TemplateRow , document : TemplateDocument ) {
86+ const indexRow = Number ( templateRow . index ) ;
87+ // TODO: Высота из формата
88+ return `<tr style="height: 20px;">
89+ <td style="text-align: center;">${ indexRow + 1 } </td>
90+ ${ ( ( ) => templateRow . row . map ( column => _getColumn ( column , indexRow , document ) ) . join ( '' ) ) ( ) }
91+ </tr>` ;
92+ }
93+
94+ function _getColumn ( templatecolumn : TemplateColumn , indexRow : number , document : TemplateDocument ) {
95+ if ( templatecolumn . c ) {
96+ let indexColumn = 0 ;
97+ let merge : TemplateMergeCells [ ] = [ ] ;
98+ let mergeSkipColumns = 0 ;
99+
100+ const rowMerge = FindRowMerge ( indexRow , document . merge ) ;
101+
102+ return templatecolumn . c . map ( ( c ) => {
103+
104+ let additionalColumns = '' ;
105+
106+ if ( c . i ) {
107+ let mergeSkipRows = 0 ;
108+ const mergeRows = rowMerge . filter ( rm => Number ( rm . c [ 0 ] ) + 1 >= indexColumn && Number ( rm . c [ 0 ] ) + 1 <= Number ( c . i [ 0 ] ) ) ;
109+ if ( mergeRows . length !== 0 ) {
110+ mergeSkipRows = mergeRows . reduce ( ( previous , current ) => {
111+ previous += Number ( current . w [ 0 ] ) + 1 ;
112+ return previous ;
113+ } , 0 ) ;
114+ }
115+ for ( let i = indexColumn + ( HasMergeColumns ( merge ) ? Number ( merge [ 0 ] . w ) : 0 ) + mergeSkipRows ; i < Number ( c . i [ 0 ] ) ; i ++ ) {
116+ additionalColumns += '<td></td>' ;
117+ }
118+ indexColumn = Number ( c . i [ 0 ] ) ;
119+ } else if ( mergeSkipColumns !== 0 ) {
120+ merge = [ ] ;
121+ mergeSkipColumns -- ;
122+ indexColumn ++ ;
123+ return ;
124+ }
125+
126+ merge = document . merge . filter ( m => m . r [ 0 ] == indexRow && m . c [ 0 ] == indexColumn ) ;
127+
128+ const hasMergeColumns = HasMergeColumns ( merge ) ;
129+ const hasMergeRows = HasMergeRows ( merge ) ;
130+
131+ mergeSkipColumns = ( hasMergeColumns ? Number ( merge [ 0 ] . w ) : 0 ) ;
132+ indexColumn ++ ;
133+
134+ let style = '' ;
135+ const cellFormat = document . format [ Number ( c . c [ 0 ] . f [ 0 ] ) - 1 ] ;
136+ if ( cellFormat ) {
137+ if ( cellFormat . horizontalAlignment ) {
138+ if ( cellFormat . horizontalAlignment [ 0 ] . toLowerCase ( ) === 'right' && ! hasMergeColumns ) {
139+ style += `float: right; text-align: right; border-top: 0; border-bottom: 0; border-left: 0;` ;
140+ } else {
141+ style += `text-align: ${ cellFormat . horizontalAlignment [ 0 ] . toLowerCase ( ) } ;` ;
142+ }
143+ }
144+
145+ if ( cellFormat . border && cellFormat . border [ 0 ] === '1' ) {
146+ style += ' border: 2px solid #fff;' ;
147+ }
148+ if ( cellFormat . leftBorder && cellFormat . leftBorder [ 0 ] === '1' ) {
149+ style += ' left-border: 2px solid #fff;' ;
150+ }
151+ if ( cellFormat . topBorder && cellFormat . topBorder [ 0 ] === '1' ) {
152+ style += ' top-border: 2px solid #fff;' ;
153+ }
154+ if ( cellFormat . bottomBorder && cellFormat . bottomBorder [ 0 ] === '1' ) {
155+ style += ' bottom-border: 2px solid #fff;' ;
156+ }
157+ if ( cellFormat . rightBorder && cellFormat . rightBorder [ 0 ] === '1' ) {
158+ style += ' right-border: 2px solid #fff;' ;
159+ }
160+
161+ if ( cellFormat . textPlacement && cellFormat . textPlacement [ 0 ] === 'Wrap' ) {
162+ style += ' white-space: normal;' ;
163+ }
164+
165+ if ( cellFormat . font && cellFormat . font [ 0 ] === '1' ) {
166+ // TODO:
167+ }
168+ }
169+ if ( style ) {
170+ style = ' style="' + style + '"' ;
171+ }
172+
173+ if ( c . c . length !== 0 && c . c [ 0 ] . parameter ) {
174+ return `${ additionalColumns } <td${ hasMergeColumns ? ` colspan=${ Number ( merge [ 0 ] . w [ 0 ] ) + 1 } ` : '' }
175+ ${ hasMergeRows ? ` rowspan=${ Number ( merge [ 0 ] . h [ 0 ] ) + 1 } ` : '' } ${ style } >
176+ <${ c . c [ 0 ] . parameter [ 0 ] } >
177+ </td>` ;
178+ } else if ( c . c [ 0 ] . tl ) {
179+ const tl = c . c [ 0 ] . tl [ 0 ] ;
180+ if ( tl ) {
181+ return `${ additionalColumns } <td${ hasMergeColumns ? ` colspan=${ Number ( merge [ 0 ] . w [ 0 ] ) + 1 } ` : '' }
182+ ${ hasMergeRows ? ` rowspan=${ Number ( merge [ 0 ] . h [ 0 ] ) + 1 } ` : '' } ${ style } >
183+ ${ tl [ 'v8:item' ] [ 0 ] [ 'v8:content' ] [ 0 ] }
184+ </td>` ;
185+ }
186+ } else if ( additionalColumns ) {
187+ return `${ additionalColumns } <td${ hasMergeColumns ? ` colspan=${ Number ( merge [ 0 ] . w [ 0 ] ) + 1 } ` : '' }
188+ ${ hasMergeRows ? ` rowspan=${ Number ( merge [ 0 ] . h [ 0 ] ) + 1 } ` : '' } ></td>` ;
189+ } else {
190+ return `<td${ hasMergeColumns ? ` colspan=${ Number ( merge [ 0 ] . w [ 0 ] ) + 1 } ` : '' }
191+ ${ hasMergeRows ? ` rowspan=${ Number ( merge [ 0 ] . h [ 0 ] ) + 1 } ` : '' } ></td>` ;
192+ }
193+ } ) . join ( '' ) ;
194+ }
195+ }
196+
197+ function FindRowMerge ( indexRow : number , merge : TemplateMergeCells [ ] ) {
198+ return merge
199+ . filter ( m =>
200+ m . h && m . w &&
201+ ( Number ( m . r [ 0 ] ) < indexRow && Number ( m . r [ 0 ] ) + Number ( m . h [ 0 ] ) >= indexRow ) ) ;
202+ }
203+
204+ function HasMergeColumns ( merge : TemplateMergeCells [ ] ) {
205+ return merge && merge . length && merge [ 0 ] . w ;
206+ }
207+ function HasMergeRows ( merge : TemplateMergeCells [ ] ) {
208+ return merge && merge . length && merge [ 0 ] . h ;
209+ }
0 commit comments