# 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 ( ) ;
}
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 ;
}