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
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;
|
|
|
|
}
|