Browse Source

Merging go and back in. Still need to fix changes from open

stew^2
Cameron Weinfurt 4 years ago
parent
commit
b6caf9890c
  1. 56
      docs/design.txt
  2. 4
      docs/specification.md
  3. 1
      goshDarn.txt
  4. 2
      sarahTest.txt
  5. BIN
      src/.Buffer.h.swo
  6. 344
      src/Buffer.cpp
  7. 7
      src/Buffer.h
  8. 14
      src/FileBrowser.cpp
  9. 42
      test.txt

56
docs/design.txt

@ -0,0 +1,56 @@
File Browser
DESIGN DOCUMENT
COMPONENT: class FileBrowser
A simple file browser. See program specification for details.
Public method:
* void run()
Runs the browser.
Implementation note: Holds the lines of text in a Buffer object. The displaying of the buffer contents and the execution of the commands is delegated to the Buffer object.
Collaborator: Buffer.
COMPONENT: class Buffer
A buffer for a simple file browser. Holds the lines of text and executes commands on them. Displays the contents of the buffer. See program specification for details on commands.
Public methods:
* Buffer()
(Compiler-generated.) Creates an empty buffer.
* void display() const
Displays the lines of text that the user is currently viewing.
* const string & file_name() const
Returns the name of the file.
* void move_to_next_page()
void move_to_previous_page()
bool open(const string & file_name)
bool go(int link)
bool back()
Executes the corresponding file viewer command on the buffer.
See program specification for details. The methods open, go, and back returns true if successful.
* int max_links()
Gives FileViewer access to the amount of links stored.
* void set_window_height(int h)
Self-explanatory.
Implementation note: Stores each line of text as a string and all the lines in a vector. Also stores the index of the line currently displayed at the top of the window, as well as the name of the file and the window height.

4
docs/specification.md

@ -49,9 +49,9 @@ Here is a description of the various commands:
* previous: The previous page is displayed. Does nothing if the first line of the file is already displayed.
* go: Go to the specified link number on the page. This opens the file to that link and displays it starting from the top line.
* go: Asks for the number of the link the user would like to visit. If the file corresponding to that link does not open, the message "ERROR: ....." is displayed.
* back: Allows you to move back to old files that you navigated to through links. **Note**: This does not apply to when files are opened through the open command.
* back: The last file that was displayed gets re-opened. If there are no files left in the history, the error message "ERROR: ...." is displayed.
* quit: Stops the program.

1
goshDarn.txt

@ -0,0 +1 @@
<p> yee haw couboy, you made it

2
sarahTest.txt

@ -0,0 +1,2 @@
<p> this is another freaking file!!
<p> here is another gosh darn <a goshDarn.txt flippin> file

BIN
src/.Buffer.h.swo

344
src/Buffer.cpp

@ -1,165 +1,179 @@
//Buffer.cpp
#include "Buffer.h"
using namespace std;
void Buffer::display() const
{
int ix_stop_line_ = ix_top_line_ + window_height_;
for (int i = ix_top_line_; i < ix_stop_line_; ++i) {
if (i < v_lines_.size())
cout << std::setw(4) << i+1 << " " << v_lines_[i];
cout << '\n';
}
}
//Pass the string by copy because I don't want to change the original, but still need to manipulate it
void Buffer::split_line(string str)
{
// Split up the lines and then push them onto the line vector
while (str.length() > maximum_length_)
{
//Initialize the substring and set the positions in the string where they need to exist
string str_part = str;
size_t curr_pos = str_part.find(" ");
size_t total_pos = curr_pos;
bool searching = true;
//While searching for the next space in a string
while (searching)
{
str_part = str_part.substr(curr_pos + 1, str_part.length());
curr_pos = str_part.find(" ");
if (curr_pos == -1)
{
searching = false;
}
else if (total_pos + curr_pos + 1 > maximum_length_)
{
searching = false;
}
else
{
total_pos += curr_pos + 1;
}
}
//Check if the string part can still be chopped
if (str_part.length() != str.length())
{
str_part = str.substr(0, total_pos);
str = str.substr(total_pos + 1, str.length());
v_lines_.push_back(str_part);
}
//Break out of the loop because there is no way to make the string shorter
//I also didn't see why I can't use break and would have to use a boolean
else
{
break;
}
}
v_lines_.push_back(str);
}
size_t Buffer::get_tag_(const string & line)
{
size_t p_tag = line.find("<p>");
size_t b_tag = line.find("<br>");
if (p_tag > b_tag)
return b_tag;
else
return p_tag;
}
bool Buffer::open(const string & new_file_name)
{
std::ifstream file(new_file_name);
if (!file)
return false;
v_lines_.clear();
//Note: the vector is cleared only after we know the file
//opened successfully.
int curr_link = 0;
std::string curr_line, line;
while(getline(file, line))
{
//Find tags and process them.
for(auto tag_loc = line.find("<a "); tag_loc != -1; tag_loc = line.find("<a", tag_loc + 1))
{
++curr_link;
//Find the length of the tag and pull out the data from the tag.
auto tag_len = line.find_first_of('>', tag_loc) - tag_loc;
std::string link_tag = line.substr(tag_loc + 3, tag_len - 3);
//Separate the link path and link name into separate strings. Assuming no spaces in the link path.
auto second_space_loc = link_tag.find_first_of(' ', 0);
std::string file_name = link_tag.substr(0, second_space_loc - 1);
std::string link_name = link_tag.substr(second_space_loc + 1);
//Adds the link as a pair to a vector of links.
v_links_.push_back({file_name, link_name});
//Reformat the link tag to match specification.
line.replace(tag_loc, tag_len + 1, "<" + link_name + ">[" + to_string(curr_link) + "]");
}
//Search for all paragraphs and breaks in the line and add them to the v_lines vector.
for(auto _tag = get_tag_(line); _tag != -1; _tag = get_tag_(line))
{
//Check to see if we have a paragraph tag, so we can add a blank line.
bool is_p = _tag == line.find("<p>");
int tag_len = is_p ? 3 : 4;
//Separate out text that should stay in the previous line and text that goes in the new line. Delete the tag in the process.
std::string extra_text = line.substr(_tag + tag_len);
line.erase(_tag);
curr_line += line;
//However, if the tag is located at the start of the file, there will be no data, so it shouldn't be added as it will be an empty line.
if(curr_line != "")
{
split_line(curr_line);
curr_line = "";
if(is_p)
{
v_lines_.push_back("");
}
}
//Move any remaining data on the line back into the line variable so that it can be processed.
line = extra_text;
}
curr_line += line;
}
// Push the contents of curr_line as it has the last line in the file.
split_line(curr_line);
ix_top_line_ = 0;
file_name_ = new_file_name;
return true;
}
bool Buffer::go(int link)
{
string f_name = v_links_[link - 1].second;
if(!open(f_name))
return false;
else
return true;
}
void Buffer::back()
{
}
//Buffer.cpp
#include "Buffer.h"
using namespace std;
void Buffer::display() const
{
int ix_stop_line_ = ix_top_line_ + window_height_;
for (int i = ix_top_line_; i < ix_stop_line_; ++i) {
if (i < v_lines_.size())
cout << std::setw(4) << i+1 << " " << v_lines_[i];
cout << '\n';
}
}
//Pass the string by copy because I don't want to change the original, but still need to manipulate it
void Buffer::split_line(string str)
{
// Split up the lines and then push them onto the line vector
while (str.length() > maximum_length_)
{
//Initialize the substring and set the positions in the string where they need to exist
string str_part = str;
size_t curr_pos = str_part.find(" ");
size_t total_pos = curr_pos;
bool searching = true;
//While searching for the next space in a string
while (searching)
{
str_part = str_part.substr(curr_pos + 1, str_part.length());
curr_pos = str_part.find(" ");
if (curr_pos == -1)
{
searching = false;
}
else if (total_pos + curr_pos + 1 > maximum_length_)
{
searching = false;
}
else
{
total_pos += curr_pos + 1;
}
}
//Check if the string part can still be chopped
if (str_part.length() != str.length())
{
str_part = str.substr(0, total_pos);
str = str.substr(total_pos + 1, str.length());
v_lines_.push_back(str_part);
}
//Break out of the loop because there is no way to make the string shorter
//I also didn't see why I can't use break and would have to use a boolean
else
{
break;
}
}
v_lines_.push_back(str);
}
size_t Buffer::get_tag_(const string & line)
{
size_t p_tag = line.find("<p>");
size_t b_tag = line.find("<br>");
if (p_tag > b_tag)
return b_tag;
else
return p_tag;
}
bool Buffer::open(const string & new_file_name)
{
std::ifstream file(new_file_name);
if (!file)
return false;
v_lines_.clear();
//Note: the vector is cleared only after we know the file
//opened successfully.
int curr_link = 0;
std::string curr_line, line;
while(getline(file, line))
{
//Find tags and process them.
for(auto tag_loc = line.find("<a "); tag_loc != -1; tag_loc = line.find("<a", tag_loc + 1))
{
++curr_link;
//Find the length of the tag and pull out the data from the tag.
auto tag_len = line.find_first_of('>', tag_loc) - tag_loc;
std::string link_tag = line.substr(tag_loc + 3, tag_len - 3);
//Separate the link path and link name into separate strings. Assuming no spaces in the link path.
auto second_space_loc = link_tag.find_first_of(' ', 0);
std::string file_name = link_tag.substr(0, second_space_loc - 1);
std::string link_name = link_tag.substr(second_space_loc + 1);
//Adds the link as a pair to a vector of links.
v_links_.push_back({file_name, link_name});
//Reformat the link tag to match specification.
line.replace(tag_loc, tag_len + 1, "<" + link_name + ">[" + to_string(curr_link) + "]");
}
//Search for all paragraphs and breaks in the line and add them to the v_lines vector.
for(auto _tag = get_tag_(line); _tag != -1; _tag = get_tag_(line))
{
//Check to see if we have a paragraph tag, so we can add a blank line.
bool is_p = _tag == line.find("<p>");
int tag_len = is_p ? 3 : 4;
//Separate out text that should stay in the previous line and text that goes in the new line. Delete the tag in the process.
std::string extra_text = line.substr(_tag + tag_len);
line.erase(_tag);
curr_line += line;
//However, if the tag is located at the start of the file, there will be no data, so it shouldn't be added as it will be an empty line.
if(curr_line != "")
{
split_line(curr_line);
curr_line = "";
if(is_p)
{
v_lines_.push_back("");
}
}
//Move any remaining data on the line back into the line variable so that it can be processed.
line = extra_text;
}
curr_line += line;
}
// Push the contents of curr_line as it has the last line in the file.
split_line(curr_line);
ix_top_line_ = 0;
file_name_ = new_file_name;
return true;
}
bool Buffer::go(int link)
{
string f_name = v_links_[link-1].first;
v_links_.clear();
add_to_hist_ = 1;
if(!open(f_name))
return false;
else
{
return true;
}
}
bool Buffer::back()
{
if(v_hist_.empty())
return false;
curr_link_itr = curr_link_itr - 1;
v_hist_.erase(curr_link_itr + 1);
if(v_hist_.empty())
return false;
add_to_hist_ = 0;
open(*curr_link_itr);
return true;
}

7
src/Buffer.h

@ -13,7 +13,7 @@
class Buffer
{
public:
void back();
bool back();
void display() const;
const std::string & file_name() const { return file_name_; }
bool go(int link);
@ -30,7 +30,10 @@ private:
std::string file_name_;
std::vector<std::string> v_lines_;
std::vector<std::pair<std::string, std::string>> v_links_;
std::vector<std::pair<std::string, std::string>> v_links_;
std::vector<std::string> v_hist_;
std::vector<std::string>::iterator curr_link_itr = v_hist_.end();
bool add_to_hist_ = 1;
int ix_top_line_ = 0;
int window_height_ = 0;
int maximum_length_ = 0;

14
src/FileBrowser.cpp

@ -9,7 +9,7 @@ void FileBrowser::display()
const string long_separator(50, '-');
const string short_separator(8, '-');
//system("cls || clear");
system("cls || clear");
if (!error_message_.empty()) {
cout << "ERROR: " + error_message_ << endl;
@ -34,8 +34,9 @@ void FileBrowser::execute_command(char command, bool & done)
{
switch (command) {
case 'b': {
buffer_.back();
break;
if(!buffer_.back())
error_message_ = "No pervious links to open";
break;
}
case 'g': {
@ -49,15 +50,14 @@ void FileBrowser::execute_command(char command, bool & done)
if (!ss) {
error_message_ = temp + " is not a valid link";
}
if (link < 1 || link > buffer_.max_links()) {
else if (link < 1 || link > buffer_.max_links()) {
error_message_ = "Could not open " + temp + " because the file is out of range";
}
if(!buffer_.go(link)){
error_message_ = "Could not open link " + link;
else if(!buffer_.go(link)){
error_message_ = "Could not open link " + temp;
}
break;
}
case 'n': {
buffer_.move_to_next_page();
break;

42
test.txt

@ -1,36 +1,6 @@
<p>This is the first line in the file.
<p>This is the second<br>and third line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into<p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second<br>and eighth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into<p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p>tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second<br>and fourteenth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into<p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second<br>and twentieth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into<p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second<br>and twenty sixth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into<p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second<br>and thirty second line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p> This is the first line in the file.
<p> This is the second <br> and third line of the file.
<p> This line has a link to the <a docs/specification.md specification> file.
<p> This line is split into <p> two paragraph tags.
<p> This line contains some<br> problematic<p> tags.
<p> This has a link to sarahs <a sarahTest.txt anotherLink> file.
Loading…
Cancel
Save