summaryrefslogtreecommitdiff
path: root/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java
blob: 85f0d91983f208bc6fee976b2c70bda785c152c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package org.jetbrains.plugins.coursecreator.format;

import com.google.gson.annotations.Expose;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.LogicalPosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.coursecreator.CCProjectService;

import java.util.ArrayList;
import java.util.List;

public class TaskFile {
  @Expose public List<TaskWindow> task_windows = new ArrayList<TaskWindow>();
  public int myIndex;
  public boolean myTrackChanges = true;

  public boolean isTrackChanges() {
    return myTrackChanges;
  }

  public void setTrackChanges(boolean trackChanges) {
    myTrackChanges = trackChanges;
  }

  public TaskFile() {}

  public void addTaskWindow(@NotNull final TaskWindow taskWindow, int index) {
    taskWindow.setIndex(index);
    task_windows.add(taskWindow);
  }

  public List<TaskWindow> getTaskWindows() {
    return task_windows;
  }

  public void setIndex(int index) {
    myIndex = index;
  }


  /**
   * @param pos position in editor
   * @return task window located in specified position or null if there is no task window in this position
   */
  @Nullable
  public TaskWindow getTaskWindow(@NotNull final Document document, @NotNull final LogicalPosition pos) {
    int line = pos.line;
    if (line >= document.getLineCount()) {
      return null;
    }
    int column = pos.column;
    int offset = document.getLineStartOffset(line) + column;
    for (TaskWindow tw : task_windows) {
      if (tw.getLine() <= line) {
        int twStartOffset = tw.getRealStartOffset(document);
        final int length = tw.getReplacementLength() > 0 ? tw.getReplacementLength() : 0;
        int twEndOffset = twStartOffset + length;
        if (twStartOffset <= offset && offset <= twEndOffset) {
          return tw;
        }
      }
    }
    return null;
  }

  /**
   * Updates task window lines
   *
   * @param startLine lines greater than this line and including this line will be updated
   * @param change    change to be added to line numbers
   */
  public void incrementLines(int startLine, int change) {
    for (TaskWindow taskTaskWindow : task_windows) {
      if (taskTaskWindow.getLine() >= startLine) {
        taskTaskWindow.setLine(taskTaskWindow.getLine() + change);
      }
    }
  }

  /**
   * Updates windows in specific line
   *
   * @param lineChange         change in line number
   * @param line               line to be updated
   * @param newEndOffsetInLine distance from line start to end of inserted fragment
   * @param oldEndOffsetInLine distance from line start to end of changed fragment
   */
  public void updateLine(int lineChange, int line, int newEndOffsetInLine, int oldEndOffsetInLine) {
    for (TaskWindow w : task_windows) {
      if ((w.getLine() == line) && (w.getStart() >= oldEndOffsetInLine)) {
        int distance = w.getStart() - oldEndOffsetInLine;
        boolean coveredByPrevTW = false;
        int prevIndex = w.getIndex() - 1;
        if (CCProjectService.indexIsValid(prevIndex, task_windows)) {
          TaskWindow prevTW = task_windows.get(prevIndex);
          if (prevTW.getLine() == line) {
            int endOffset = prevTW.getStart() + prevTW.getLength();
            if (endOffset >= newEndOffsetInLine) {
              coveredByPrevTW = true;
            }
          }
        }
        if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) {
          w.setStart(distance + newEndOffsetInLine);
          w.setLine(line + lineChange);
        }
      }
    }
  }
}