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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
#include "document_impl.h"
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
//update current document
void Document::add_line_update_current(const full_action& act)const {
if (act.get_num() == num_of_lines_current) {
current_update.push_back(act.get_text());
++num_of_lines_current;
return;
}
auto it = current_update.begin();
//update iterator so it points to right position
for (int i = 0; i < act.get_num(); ++i) {
it++;
}
//insert before
current_update.insert(it, act.get_text());
++num_of_lines_current;
}
void Document::del_line_update_current(const full_action& act)const {
//ja rinda nr 0 tad push front jauno tekstu
auto it = current_update.begin();
//update iterator so it points to right position
for (int i = 0; i < act.get_num(); ++i) {
++it;
}
current_update.erase(it);
--num_of_lines_current;
}
void Document::update_current(const full_action& act)const {
switch (act.get_action()) {
case action::insert: {
add_line_update_current(act);
break;
}
case action::del: {
del_line_update_current(act);
break;
}
}
}
void Document::add_line(const std::string& str, int line_nr) {
try {
if (line_nr < 0) throw std::runtime_error{ "negative line number" };
else if (line_nr >= num_of_lines) {
for (int i = num_of_lines; i < line_nr; ++i, ++num_of_lines) {
//add empty lines
actions.push_back({ action::insert, "", i });
}
actions.push_back({ action::insert, str, line_nr });
++num_of_lines;
}
else {
actions.push_back({ action::insert, str, line_nr });
++num_of_lines;
}
}
catch (const std::runtime_error& err) {
std::cout << "error : " << err.what() << std::endl;
}
}
void Document::push_back(const std::string& str) {
add_line(str, num_of_lines);
}
void Document::del_line(int line_nr) {
try {
if (line_nr < 0) throw std::runtime_error{ "negative line asked to delete" };
else if (!num_of_lines || ++line_nr > num_of_lines)
throw std::runtime_error{ "cant delete line that doesnt exist" };
else {
actions.push_back({ action::del, "", --line_nr });
--num_of_lines;
}
}
catch (const std::runtime_error& err) {
std::cout << "error : " << err.what() << std::endl;
}
}
void Document::print() const {
//find a way to know how many actions are updated
if (actions_updated != actions.size()) {
//make updates
for (int i = actions_updated; i < actions.size(); ++i) {
update_current(actions[i]);
}
actions_updated = actions.size();
}
int index{0};
for (auto& l : current_update) {
std::cout << "[ " << index++ << " ]\t" << l << std::endl;
}
}
void Document::update_line_count(const std::vector<full_action>& vec,
int& lines_current, int& lines) {
//update theoretical lines
switch (vec[vec.size() - 1].get_action()) {
case action::insert: {--lines; break; }
case action::del: {++lines; break; }
}
for (int i = 0; i < vec.size(); ++i) {
switch (vec[i].get_action()) {
case action::insert: {
if(i < actions_updated) //check if current lines update happened
--lines_current;
break;
}
case action::del: {
if (i < actions_updated) //check if current lines update happened
++lines_current;
break;
}
}
}
}
void Document::undo() {
if (actions.empty()) throw std::runtime_error{ "undo cant be made" };
//update current lines and theoretical lines
update_line_count(actions, num_of_lines_current, num_of_lines);
//delete last action
actions.pop_back();
//have to create print from scratch
current_update = lines;
actions_updated = 0;
}
|