|
|
@@ -974,187 +974,6 @@ App.controller(
|
|
|
}
|
|
|
)
|
|
|
|
|
|
-App.factory('synctex', function (ide, $http, $q) {
|
|
|
- const synctex = {
|
|
|
- syncToPdfInFlight: false,
|
|
|
- syncToCodeInFlight: false,
|
|
|
-
|
|
|
- syncToPdf(cursorPosition) {
|
|
|
- const deferred = $q.defer()
|
|
|
-
|
|
|
- const docId = ide.editorManager.getCurrentDocId()
|
|
|
- if (docId == null) {
|
|
|
- deferred.reject()
|
|
|
- return deferred.promise
|
|
|
- }
|
|
|
- const doc = ide.fileTreeManager.findEntityById(docId)
|
|
|
- if (doc == null) {
|
|
|
- deferred.reject()
|
|
|
- return deferred.promise
|
|
|
- }
|
|
|
- let path = ide.fileTreeManager.getEntityPath(doc)
|
|
|
- if (path == null) {
|
|
|
- deferred.reject()
|
|
|
- return deferred.promise
|
|
|
- }
|
|
|
-
|
|
|
- // If the root file is folder/main.tex, then synctex sees the
|
|
|
- // path as folder/./main.tex
|
|
|
- const rootDocDirname = ide.fileTreeManager.getRootDocDirname()
|
|
|
- if (rootDocDirname != null && rootDocDirname !== '') {
|
|
|
- path = path.replace(RegExp(`^${rootDocDirname}`), `${rootDocDirname}/.`)
|
|
|
- }
|
|
|
-
|
|
|
- const { row, column } = cursorPosition
|
|
|
-
|
|
|
- this.syncToPdfInFlight = true
|
|
|
-
|
|
|
- $http({
|
|
|
- url: `/project/${ide.project_id}/sync/code`,
|
|
|
- method: 'GET',
|
|
|
- params: {
|
|
|
- file: path,
|
|
|
- line: row + 1,
|
|
|
- column,
|
|
|
- clsiserverid: ide.clsiServerId,
|
|
|
- },
|
|
|
- })
|
|
|
- .then(response => {
|
|
|
- this.syncToPdfInFlight = false
|
|
|
- const { data } = response
|
|
|
- return deferred.resolve(data.pdf || [])
|
|
|
- })
|
|
|
- .catch(response => {
|
|
|
- this.syncToPdfInFlight = false
|
|
|
- const error = response.data
|
|
|
- return deferred.reject(error)
|
|
|
- })
|
|
|
-
|
|
|
- return deferred.promise
|
|
|
- },
|
|
|
-
|
|
|
- syncToCode(position, options) {
|
|
|
- if (options == null) {
|
|
|
- options = {}
|
|
|
- }
|
|
|
- const deferred = $q.defer()
|
|
|
- if (position == null) {
|
|
|
- deferred.reject()
|
|
|
- return deferred.promise
|
|
|
- }
|
|
|
-
|
|
|
- // FIXME: this actually works better if it's halfway across the
|
|
|
- // page (or the visible part of the page). Synctex doesn't
|
|
|
- // always find the right place in the file when the point is at
|
|
|
- // the edge of the page, it sometimes returns the start of the
|
|
|
- // next paragraph instead.
|
|
|
- const h = position.offset.left
|
|
|
-
|
|
|
- // Compute the vertical position to pass to synctex, which
|
|
|
- // works with coordinates increasing from the top of the page
|
|
|
- // down. This matches the browser's DOM coordinate of the
|
|
|
- // click point, but the pdf position is measured from the
|
|
|
- // bottom of the page so we need to invert it.
|
|
|
- let v
|
|
|
- if (
|
|
|
- options.fromPdfPosition &&
|
|
|
- (position.pageSize != null ? position.pageSize.height : undefined) !=
|
|
|
- null
|
|
|
- ) {
|
|
|
- v = position.pageSize.height - position.offset.top || 0 // measure from pdf point (inverted)
|
|
|
- } else {
|
|
|
- v = position.offset.top || 0 // measure from html click position
|
|
|
- }
|
|
|
-
|
|
|
- // It's not clear exactly where we should sync to if it wasn't directly
|
|
|
- // clicked on, but a little bit down from the very top seems best.
|
|
|
- if (options.includeVisualOffset) {
|
|
|
- v += 72 // use the same value as in pdfViewer highlighting visual offset
|
|
|
- }
|
|
|
-
|
|
|
- this.syncToCodeInFlight = true
|
|
|
-
|
|
|
- $http({
|
|
|
- url: `/project/${ide.project_id}/sync/pdf`,
|
|
|
- method: 'GET',
|
|
|
- params: {
|
|
|
- page: position.page + 1,
|
|
|
- h: h.toFixed(2),
|
|
|
- v: v.toFixed(2),
|
|
|
- clsiserverid: ide.clsiServerId,
|
|
|
- },
|
|
|
- })
|
|
|
- .then(response => {
|
|
|
- this.syncToCodeInFlight = false
|
|
|
- const { data } = response
|
|
|
- if (
|
|
|
- data.code != null &&
|
|
|
- data.code.length > 0 &&
|
|
|
- data.code[0].file !== ''
|
|
|
- ) {
|
|
|
- const doc = ide.fileTreeManager.findEntityByPath(data.code[0].file)
|
|
|
- if (doc == null) {
|
|
|
- deferred.reject()
|
|
|
- }
|
|
|
- return deferred.resolve({ doc, line: data.code[0].line })
|
|
|
- } else if (data.code[0].file === '') {
|
|
|
- ide.$scope.sync_tex_error = true
|
|
|
- setTimeout(() => (ide.$scope.sync_tex_error = false), 4000)
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(response => {
|
|
|
- this.syncToCodeInFlight = false
|
|
|
- const error = response.data
|
|
|
- return deferred.reject(error)
|
|
|
- })
|
|
|
-
|
|
|
- return deferred.promise
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- return synctex
|
|
|
-})
|
|
|
-
|
|
|
-App.controller('PdfSynctexController', function ($scope, synctex, ide) {
|
|
|
- this.cursorPosition = null
|
|
|
-
|
|
|
- $scope.$watch(
|
|
|
- () => synctex.syncToPdfInFlight,
|
|
|
- value => ($scope.syncToPdfInFlight = value)
|
|
|
- )
|
|
|
- $scope.$watch(
|
|
|
- () => synctex.syncToCodeInFlight,
|
|
|
- value => ($scope.syncToCodeInFlight = value)
|
|
|
- )
|
|
|
-
|
|
|
- ide.$scope.$on('cursor:editor:update', (event, cursorPosition) => {
|
|
|
- this.cursorPosition = cursorPosition
|
|
|
- })
|
|
|
-
|
|
|
- $scope.syncToPdf = () => {
|
|
|
- if (this.cursorPosition == null) {
|
|
|
- return
|
|
|
- }
|
|
|
- synctex.syncToPdf(this.cursorPosition).then(highlights => {
|
|
|
- $scope.pdf.highlights = highlights
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- ide.$scope.$on('cursor:editor:syncToPdf', $scope.syncToPdf)
|
|
|
-
|
|
|
- $scope.syncToCode = function () {
|
|
|
- synctex
|
|
|
- .syncToCode($scope.pdf.position, {
|
|
|
- includeVisualOffset: true,
|
|
|
- fromPdfPosition: true,
|
|
|
- })
|
|
|
- .then(function (data) {
|
|
|
- const { doc, line } = data
|
|
|
- ide.editorManager.openDoc(doc, { gotoLine: line })
|
|
|
- })
|
|
|
- }
|
|
|
-})
|
|
|
-
|
|
|
App.controller('ClearCacheModalController', function ($scope, $modalInstance) {
|
|
|
$scope.state = { error: false, inflight: false }
|
|
|
|