You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

684 lines
15 KiB
C

#include "texted.h"
#define MAX_SIZE 1048576
/* ********************************************************************************************************************************************** */
// STUFF TO IMPLEMENT
// ******DONE****** 1. Characters should be removed from array after backspace (maybe keep track of which element in the array the cursor is on.
// ******DONE****** 2. Enter should add newline character to array.
// ******DONE****** 3. Backspace and Left Arrow at first character in row should move up to the last character on the previous row. (vice versa for right arrow)
// ********(PAGE UP AND) PAGE DOWN SOMETIMES DOESN'T MOVE REAL CURSOR ACCORDINGLY - TEXTCOUNTER SHOULD BE ADJUSTED******** 4. Page scrolling up/down (initially with page up/page down keys). - Idea: Implement by printing from nth new line character till first null character.
// 5. (OPTIONAL): Convert the mainwin into a pad, to make scrolling easier.
// **KIND OF DONE** 6. Word wrapping.
// ******DONE****** 7. Getting Save File Location from argv
// ******DONE?***** 8. Up Arrow and Down Arrow Keys.
// ******DONE****** 9. Integrate with file manager program.
// ******DONE****** 10. Opening and editing text files
// **MOSTLY DONE*** 11. Save Dialog.
// ******DONE****** 12. Insert character into array after pressing left arrow and typing a character.
// SOLVE ERROR WITH LAST LINE IN A FILE (IT DOESN'T HAVE MAINX CHARACTERS AND IT DOESN'T HAVE TWO NEWLINES)
// ******DONE****** 13. Backspace at first character ignores spaces.
// ******DONE?***** 14. Adding character at last line of window.
// ******DONE?***** 15. Page down/Page up with word wrapping.
/* ********************************************************************************************************************************************** */
int run(char* dir) {
char* text;
char* saveLocation;
// char* tempSaveLoc;
int textCounter;
int selRow=1;
// int numCharsCurrent;
// int numCharsNext;
int selCol=1;
int xSize,ySize,mainX,mainY;
int charArrayCounter;
FILE* myFile;
int ch;
int numLines;
bool newLineFound;
// int textIndex;
// char* shortText;
int upArrowDistance;
int charsOnLine;
text = malloc(MAX_SIZE * (sizeof(char)));
initscr();
noecho();
// cbreak();
raw();
getmaxyx(stdscr,ySize,xSize);
// mvwaddstr(stdscr,2,5,"^S - Save | ^C - Quit | ^R - Reset Cursor");
mvwaddstr(stdscr,2,5,"^S - Save | ^C - Quit | <Page Down> - Scroll Down | <Page Up> - Scroll Up");
// WINDOW* boxwin = newwin(ySize-7,xSize-8,5,5);
WINDOW* mainwin = newwin(ySize-7,xSize-9,5,5);
keypad(mainwin,true);
// box(boxwin,0,0);
getmaxyx(mainwin,mainY,mainX);
refresh();
wrefresh(mainwin);
// wrefresh(boxwin);
wmove(mainwin,selRow,selCol);
// ch = wgetch(mainwin);
ch = ' ';
textCounter=0;
numLines=0;
int numNewLinesFound=0;
int indexToBegin=0;
FILE* readFile;
// int tempSelRow,tempSelCol;
// if (argc > 1) {
if (readFile = fopen(dir,"r")) {
fread(text,MAX_SIZE,1,readFile);
printFromIndex(mainwin,text,0,1,1,0);
// } else {
// strcpy(argv[1],tempSaveLoc);
}
// }
wmove(mainwin,selRow,selCol);
while (ch != ('s' & 0x1f) && (ch != ('c' & 0x1f))) {
indexToBegin=0;
numNewLinesFound=0;
charsOnLine=0;
if (numLines > 0) {
for (int i=0;i<strlen(text);i++) {
if (numNewLinesFound==numLines) {
indexToBegin=i;
break;
}
if (*(text+i)=='\n') {
numNewLinesFound++;
charsOnLine=0;
} else {
charsOnLine++;
}
if (charsOnLine>=mainX-2){
numNewLinesFound++;
charsOnLine=0;
}
}
}
// if (indexToBegin!=0){
printFromIndex(mainwin,text,indexToBegin,selRow,selCol,numLines);
// }
// box(mainwin,0,0);
// getyx(mainwin,selRow,selCol);
wmove(stdscr,1,1);
wclrtoeol(stdscr);
mvwprintw(stdscr,1,1,"%d,%d",selRow,selCol);
mvwprintw(stdscr,3,1,"%c",findCharInArray(text,2,1,numLines));
wmove(mainwin,selRow,selCol);
ch = wgetch(mainwin);
switch (ch) {
case 7:
case KEY_BACKSPACE:
case 8:
case 127:
if (selCol > 1) {
wmove(mainwin,selRow,--selCol);
wdelch(mainwin);
textCounter--;
shiftElementsDown(text,textCounter);
} else if (selCol == 1 && selRow > 1) {
textCounter--;
--selRow;
selCol=findLastChar(mainwin,selRow,mainX)+charToNewLine(text,textCounter);
wmove(mainwin,selRow,selCol);
shiftElementsDown(text,textCounter);
}
break;
case KEY_LEFT:
if (selCol > 1) {
wmove(mainwin,selRow,--selCol);
textCounter--;
} else if (selCol == 1 && selRow > 1) {
textCounter--;
--selRow;
selCol=findLastChar(mainwin,selRow,mainX)+charToNewLine(text,textCounter);
if (selCol==2) {
selCol--;
// *(int*)0=0;
}
wmove(mainwin,selRow,selCol);
}
break;
case KEY_RIGHT:
// if (!(isLastChar(mainwin,selRow,selCol,mainX))) {
if (*(text+textCounter) != '\0') {
if (*(text+textCounter) != '\n' && selCol<mainX-2) {
wmove(mainwin,selRow,++selCol);
} else {
selCol=1;
wmove(mainwin,++selRow,selCol);
}
textCounter++;
// mvwprintw(mainwin,6,6,"%d",mvwinch(mainwin,selRow,selCol));
}
break;
case KEY_HOME:
textCounter-=selCol-1;
selCol=1;
wmove(mainwin,selRow,selCol);
break;
case KEY_DOWN:
if (selCol == 1 && (*(text+textCounter+(findLastChar(mainwin,selRow,mainX)))) != '\0' && selRow<mainY-2) {
while (*(text+textCounter) != '\n' && selCol<mainX-2){
textCounter++;
selCol++;
}
textCounter++;
selCol=1;
/*
if (findLastChar(mainwin,selRow,mainX) > mainX-3) {
textCounter--;
}
textCounter += (findLastChar(mainwin,selRow,mainX));
// textCounter += (findLastCharWithArray(mainwin,stdscr,selRow,mainX,text,textCounter,numLines));
// selCol=1;
*/
wmove(mainwin,++selRow,selCol);
}
break;
case KEY_UP:
if (selRow-1 > 0 && (selCol == 1 && (*(text+textCounter-(findLastChar(mainwin,selRow-1,mainX)))) != '\0')) {
int selColOfNewLine = 500;
newLineFound=false;
upArrowDistance=0;
for (int i=1;i<mainX;i++) {
// if (*(text+textCounter+1) == '\n') {
// newLineFound=true;
// }
if (i==mainX-1){
upArrowDistance=mainX-1;
break;
}
if (textCounter==i) {
upArrowDistance=textCounter+1;
break;
}
if (i == findLastChar(mainwin,selRow-1,mainX)) {
upArrowDistance = findLastChar(mainwin,selRow-1,mainX);
break;
}
if (*(text+textCounter-i) == '\n') {
if (i<=2) {
upArrowDistance=i;
selColOfNewLine=i;
} else {
upArrowDistance=i-1;
}
if (newLineFound) {
//if (findLastChar(mainwin,selRow-1,mainX) == 0) {
// upArrowDistance=2;
//}
break;
}
newLineFound=true;
}
}
textCounter-=upArrowDistance-1;
// textCounter -= (findLastChar(mainwin,selRow-1,mainX));
// selCol=1;
wmove(mainwin,--selRow,selCol);
// *(int*)0=0;
}
break;
case 10:
// wmove(mainwin,selRow+1,1);
if (selRow < mainY-2) {
wmove(mainwin,++selRow,1);
shiftElementsUp(text,textCounter);
*(text+textCounter) = '\n';
textCounter++;
// selCol=1;
selCol=1;
}
break;
case KEY_DC:
// abort();
if (!(isLastChar(mainwin,selRow,selCol,mainX))) {
wmove(mainwin,selRow,selCol+1);
wdelch(mainwin);
// textCounter--;
shiftElementsDown(text,textCounter);
}
break;
// case (('r' & 0x1f)):
// wmove(mainwin,selRow,selCol);
// break;
case (('s' & 0x1f)):
// abort();
// shortText = shortenString(text);
// if (argc > 1) {
saveLocation = getSaveLoc(mainX,mainY,dir);
// } else {
// saveLocation = getSaveLoc(mainX,mainY,"$$$");
// }
if (saveLocation == "$$$") {
ch = ' ';
wmove(mainwin,selRow,selCol);
break;
}
// myFile = fopen("savedFile.txt","w");
myFile = fopen(saveLocation,"w");
mvwaddstr(stdscr,1,1,saveLocation);
charArrayCounter=0;
do {
fputc(*(text+charArrayCounter),myFile);
charArrayCounter++;
// } while (charArrayCounter < (strlen(shortText)));
} while (*(text+charArrayCounter) != '\0');
if (*(text+charArrayCounter) != '\n') {
fputc('\n',myFile);
}
// fputc('\0',myFile);
fclose(myFile);
// wgetch(mainwin);
break;
case KEY_NPAGE:
if (selRow > 1) {
numLines++;
selRow--;
wmove(mainwin,selRow,selCol);
} else {
if (selCol == 1) {
numLines++;
while (*(text+textCounter) != '\n' && selCol<mainX-2){
textCounter++;
selCol++;
}
textCounter++;
selCol=1;
// //textCounter += (findLastChar(mainwin,selRow,mainX));
wmove(mainwin,selRow,selCol);
}
}
break;
case KEY_PPAGE:
if (selRow >= mainY-2 && selCol == 1 && selRow > 1) {
textCounter -= (findLastChar(mainwin,selRow-1,mainX));
selRow--;
}
if (numLines > 0){
selCol=1;
wmove(mainwin,selRow,selCol);
numLines--;
selRow++;
}
// if (numLines == 0) {
// selRow++;
// }
break;
default:
// waddch(mainwin,ch);
mvwinsch(mainwin,selRow,selCol,ch);
if (*(text+textCounter+1-1) != '\0') {
shiftElementsUp(text,textCounter);
}
*(text + textCounter) = ch;
textCounter++;
if (selCol >= mainX-1) {
selCol=2;
selRow++;
wmove(mainwin,selRow,selCol);
} else {
// selCol++;
// /*Temporary uncomment*/
// selCol++;
// wmove(mainwin,selRow,selCol+1);
wmove(mainwin,selRow,++selCol);
}
// mvwprintw(stdscr,1,2,"%d",*(text+textCounter-1));
// mvwprintw(mainwin,6,6,"%d",ch);
break;
}
// mvwprintw(mainwin,3,3,"%d",textCounter);
// box(boxwin,0,0);
}
endwin();
return 0;
}
char* shortenString (char* origString) {
int numNullChars = 0;
char* newString = malloc((strlen(origString)+1) * (sizeof(char)));
// for (int i=0;i<strlen(newString)+1;i++) {
// (*newString+i) = (*origString+i);
strncpy(newString,origString,strlen(newString)+1);
// }
return newString;
}
void shiftElementsDown(char* arr,int arrCounter){
// SHIFTS ELEMENTS LEFT
int lastElement = strlen(arr)-1;
for (int i=arrCounter+1;i<strlen(arr)+10;i++){
*(arr+i-1) = *(arr+i);
}
*(arr+lastElement)='\0';
}
void shiftElementsUp(char* arr,int arrCounter) {
// SHIFTS ELEMENTS RIGHT
for (int i=strlen(arr)+2;i>=arrCounter;i--) {
*(arr+i+1) = *(arr+i);
}
*(arr+arrCounter) = '\0';
}
char* getSaveLoc(int mainX,int mainY, char* tempSaveLoc) {
WINDOW* saveDiag = newwin(8,40,((mainY/2)-4),((mainX/2)-20));
char* saveLoc = malloc(SAVE_LOC_SIZE * sizeof(char));
box(saveDiag,0,0);
refresh();
wrefresh(saveDiag);
mvwaddstr(saveDiag,1,1,"Save to?");
mvwhline(saveDiag,4,2,0,36);
wmove(saveDiag,3,2);
int i=0;
char ch = 65;
raw();
int saveY,saveX;
// cbreak();
if (tempSaveLoc != "$$$") {
do {
wmove(saveDiag,3,i+2);
waddch(saveDiag,*(tempSaveLoc+i));
*(saveLoc+i) = *(tempSaveLoc+i);
i++;
} while (i<strlen(tempSaveLoc));
}
do {
ch = wgetch(saveDiag);
if (ch == 10) {
break;
}
if (ch == ('c' & 0x1f)) {
break;
}
getyx(saveDiag,saveY,saveX);
if (ch == 127) {
if (saveX > 2) {
wmove(saveDiag,3,i+1);
// wdelch(saveDiag);
waddch(saveDiag,32);
wmove(saveDiag,3,i+1);
*(saveLoc+i-1) = '\0';
i--;
}
} else {
wmove(saveDiag,3,i+2);
waddch(saveDiag,ch);
*(saveLoc+i) = ch;
i++;
}
refresh();
wrefresh(saveDiag);
} while (ch != 10 && ch != ('c' & 0x1f));
// raw();
wclear(saveDiag);
refresh();
wrefresh(saveDiag);
// return shortenString(saveLoc);
if (ch == ('c' & 0x1f)) {
return "$$$";
}
return saveLoc;
}
int findLastChar(WINDOW* mainwin,int selRow,int mainX) {
int selCol=0;
for (int i=mainX-1;i>=1;i--){
if (mvwinch(mainwin,selRow,i) != 32) {
selCol=i;
break;
}
}
if (selCol==0){
return selCol;
}
return selCol+1;
}
int findLastCharWithArray(WINDOW* mainwin,WINDOW* std,int selRow,int mainX,char* text, int textCounter,int numLines) {
int selCol=0;
for (int i=0;i>mainX;i++){
// if (findCharInArray(text,selRow,i+1,numLines) == mvwinch(mainwin,selRow+1,1)) {
mvwprintw(stdscr,3,1,"%c\n",findCharInArray(text,selRow,i+1,numLines));
if (findCharInArray(text,selRow,i+1,numLines) == '\n') {
abort();
selCol=i;
// *(int*)0 = 0;
break;
}
}
return selCol+1;
}
bool isLastChar(WINDOW* mainwin,int selRow,int selCol,int mainX) {
for (int i=selCol;i<mainX-1;i++) {
if (mvwinch(mainwin,selRow,i) != 32) {
return false;
}
}
return true;
}
void printFromIndex(WINDOW* mainwin,char* text,int index,int selRow,int selCol,int numLines) {
wclear(mainwin);
refresh();
wrefresh(mainwin);
int mainY,mainX;
getmaxyx(mainwin,mainY,mainX);
// int index=indexToBegin;
int selRowTemp=1;
int selColTemp=1;
while((*(text+index) != '\0') && (selRowTemp < mainY-1)) {
mvwaddch(mainwin,selRowTemp,selColTemp,*(text+index));
selColTemp++;
if (*(text+index) == '\n') {
selRowTemp++;
selColTemp=1;
}
if (selColTemp >= mainX-1) {
selColTemp=1;
selRowTemp++;
// index++;
wmove(mainwin,selRowTemp,selColTemp);
}
index++;
}
// box(boxwin,0,0);
refresh();
// wrefresh(boxwin);
// wmove(mainwin,selRow,selCol);
wmove(mainwin,numLines,selCol);
if (numLines == 0) {
wmove(mainwin,++selRow,selCol);
}
}
char findCharInArray(char* charArray, int selRow, int selCol, int numLines) {
int indexToBegin=0;
int numNewLinesFound=0;
if (numLines > 0) {
for (int i=0;i<strlen(charArray);i++) {
if (numNewLinesFound==numLines) {
indexToBegin=i;
break;
}
if (*(charArray+i)=='\n') {
numNewLinesFound++;
}
}
}
// *(int*)0 = 0;
selRow--;
// selCol++;
int index=indexToBegin;
int curRow=0;
while(curRow < selRow) {
index++;
if (*(charArray+index) == '\n') {
curRow++;
}
if (selRow == curRow) {
break;
}
}
for (int i=0;i<selCol;i++){
index++;
}
// return 'a';
return *(charArray+index);
}
int charToNewLine(char* text,int textCounter) {
int returnVal=0;
while (*(text+textCounter) == 32 || *(text+textCounter) == '\n'){
returnVal++;
textCounter--;
}
return returnVal-1;
}