home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Bila Vrana
/
BILA_VRANA.iso
/
028A
/
MEDIT151.ZIP
/
MGUI
/
MEDIT
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-07
|
20KB
|
790 lines
/*
* This file is part of the M-Edit program (Copyright 1996 by Vincenzo Morello)
* Permission to use is hereby granted for any purpose.
*
* Contains file handling and utility callbacks.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#if defined __TURBOC__ || defined _MSC_VER
#include <io.h>
#define R_OK 04
#else
#include <unistd.h>
#endif
#include "mgui.h"
#include "medit.h"
#include "me.h"
void LoadPrefs(void);
void SetWindowOptions(MOBJECT shell);
/*
* This array holds open windows OBJECT id
*/
MOBJECT windows[MAX_N_WINDOW];
/*
* This string points to the pathname of the configuration file
*/
char pref_fname[MAXPATHLEN+1];
/*
* Free an undo item
*/
static void FreeUndo(UNDO_DATA *pud)
{
if (pud->oldtext)
free(pud->oldtext);
if (pud->newtext)
free(pud->newtext);
free(pud);
}
/*
* Free all queued undo items for a window
*/
static void FreeUndoList(FILE_DATA *pfd)
{
UNDO_DATA *pud, *tmp;
pud = pfd->first_undo;
while (pud) {
tmp = pud;
pud = pud->next;
FreeUndo(tmp);
}
pfd->first_undo = NULL;
pfd->curr_undo = NULL;
pfd->undo_level = 0;
}
/*
* Read a file and ruturn the stream pointer and read-only status
*/
static char *LoadFile(char *filename, int *ro)
{
FILE *fp;
char str[256];
char *buff;
struct stat sb;
int nread;
if (stat(filename, &sb) == -1) {
sprintf(str, "Error accessing file:\n%s", filename);
MMessageDialog("Error", str, " Ok ", NULL);
return NULL;
}
if (sb.st_size > (long)INT_MAX) {
MMessageDialog("Sorry", "File is too large !", " Ok ", NULL);
return NULL;
}
if ((fp=fopen(filename, "r+")) == NULL) {
if ((fp=fopen(filename, "r")) == NULL) {
sprintf(str, "Opening file:\n%s", filename);
MMessageDialog("Error", str, " Ok ", NULL);
return NULL;
}
*ro = True;
}
else {
*ro = False;
}
if ((buff = malloc((int)sb.st_size+1)) == NULL) {
MMessageDialog("ERROR", "Not Enough Memory,\nSorry", " Ok ", NULL);
}
else {
nread = fread(buff, 1, (int)sb.st_size, fp);
buff[nread] = '\0';
}
fclose(fp);
return buff;
}
/*
* This callback handles cursor position change showing
*/
void CursorPosCB(MOBJECT p, EDIT_CURS *pc, void *ad)
{
FILE_DATA *pfd;
MOBJECT shell;
char buff[64];
shell = MObjectShell(p);
pfd = (FILE_DATA *)MObjectGetUserData(shell);
if (pfd == NULL)
return;
sprintf(buff, "%4d", pc->pos_x + 1);
MObjectSetText(pfd->curs_x_label, buff);
sprintf(buff, "%4d", pc->pos_y + 1);
MObjectSetText(pfd->curs_y_label, buff);
}
void AddUndoData(FILE_DATA *pfd,
char *oldtext, int start, int oldlen,
char *newtext, int newlen)
{
UNDO_DATA *pud, *tmp;
if (pfd->curr_undo || pfd->first_undo) {
/*
* Cut any Undo-ed data (it cannot be Redo-ed)
*/
if (pfd->curr_undo) {
pud = pfd->curr_undo->next;
pfd->curr_undo->next = NULL;
}
else {
pud = pfd->first_undo;
pfd->first_undo = NULL;
}
while (pud) {
tmp = pud;
pud = pud->next;
FreeUndo(tmp);
pfd->undo_level--;
}
}
if (pfd->undo_level == UNDO_DEPTH) {
/*
* Cut the oldest undo data when maximum depth is reached
*/
tmp = pfd->first_undo;
pfd->first_undo = pfd->first_undo->next;
if (pfd->first_undo)
pfd->first_undo->prev = NULL;
FreeUndo(tmp);
pfd->undo_level--;
}
pud = (UNDO_DATA *)calloc(1, sizeof(UNDO_DATA));
if (pud == NULL) {
if (oldtext)
free(oldtext);
if (newtext)
free(newtext);
return;
}
pud->start = start;
pud->oldlen = oldlen;
pud->newlen = newlen;
pud->oldtext = oldtext;
pud->newtext = newtext;
if (pfd->curr_undo)
pfd->curr_undo->next = pud;
pud->prev = pfd->curr_undo;
pfd->curr_undo = pud;
if (pfd->first_undo == NULL)
pfd->first_undo = pud;
pfd->undo_level++;
}
/*
* This callback handles the 'modified' status and queues undo items
*/
void TextChangedCB(MOBJECT p, EDIT_CHANGE *ped, void *ad)
{
FILE_DATA *pfd;
MOBJECT shell;
char *oldtext = NULL;
char *newtext = NULL;
shell = MObjectShell(p);
pfd = MObjectGetUserData(shell);
if (!pfd->modified) {
/*
* Set file modified status to True
*/
MObjectSetText(pfd->modified_label, "*");
pfd->modified = True;
}
if (ped->len > 0 && (oldtext = malloc(ped->len+1)) == NULL) {
return;
}
if (ped->change_len > 0 && (newtext = malloc( ped->change_len+1)) == NULL) {
if (oldtext)
free(oldtext);
return;
}
if (ped->len > 0) {
strncpy(oldtext, ped->current_text+ped->pos, ped->len);
oldtext[ped->len] = '\0';
}
if (ped->change_len > 0) {
strncpy(newtext, ped->change, ped->change_len);
newtext[ped->change_len] = '\0';
}
AddUndoData(pfd, oldtext, ped->pos, ped->len, newtext, ped->change_len);
}
/*
* This callback handles user's undo requests
*/
void UndoCB(MOBJECT p, void *od, void *ad)
{
FILE_DATA *pfd;
UNDO_DATA *pud;
MOBJECT shell;
shell = MObjectShell(ad);
pfd = MObjectGetUserData(shell);
pud = pfd->curr_undo;
if (pud == NULL) {
MBeep();
return;
}
MEditChangeText(pfd->edit,
pud->start, pud->newlen,
(pud->oldtext ? pud->oldtext : ""),
pud->oldlen);
pfd->curr_undo = pud->prev;
if (!pfd->modified) {
/*
* Set file modified status to True
*/
MObjectSetText(pfd->modified_label, "*");
pfd->modified = True;
}
}
/*
* This callback handles user's redo requests
*/
void RedoCB(MOBJECT p, void *od, void *ad)
{
FILE_DATA *pfd;
UNDO_DATA *pud;
MOBJECT shell;
shell = MObjectShell(ad);
pfd = MObjectGetUserData(shell);
pud = (pfd->curr_undo ? pfd->curr_undo->next : pfd->first_undo);
if (pud == NULL) {
MBeep();
return;
}
MEditChangeText(pfd->edit,
pud->start, pud->oldlen,
(pud->newtext ? pud->newtext : ""),
pud->newlen);
pfd->curr_undo = pud;
if (!pfd->modified) {
/*
* Set file modified status to True
*/
MObjectSetText(pfd->modified_label, "*");
pfd->modified = True;
}
}
/*
* This callback handles user's save request
*/
void SaveCB(MOBJECT p, void *od, void *ad)
{
MOBJECT shell = (MOBJECT)ad;
FILE_DATA *pfd = (FILE_DATA *)MObjectGetUserData(shell);
FILE *fp;
char str[256];
char *buff;
int len;
if (pfd->pathname[0] == '\0') {
if (pfd->modified) {
if (!MFileSelection("Save File As ...", EXT,
pfd->filename, pfd->pathname, True))
return;
strcat(pfd->pathname, pfd->filename);
MObjectSetText(pfd->fname_label, pfd->pathname);
}
else
MMessageDialog("Warning", "No file open !", " Ok ", NULL);
return;
}
if (pfd->read_only) {
sprintf(str, "File: %s\nis read only!", pfd->pathname);
MMessageDialog("Warning", str, " Ok ", NULL);
return;
}
if (!pfd->modified) {
sprintf(str, "File:\n%s\nhas not been modified.\nSave anyway ?", pfd->pathname);
if (MMessageDialog("Warning", str, " Yes ", " Abort", NULL) != 0)
return;
}
if ((fp = fopen(pfd->pathname, "w")) == NULL) {
sprintf(str, "Cannot open file:\n%s\nfor writing!", pfd->pathname);
MMessageDialog("Warning", str, " Ok ", NULL);
return;
}
buff = MObjectGetText(pfd->edit, NULL);
if (buff) {
len = strlen(buff);
if (fwrite(buff, 1, len, fp) != len)
MMessageDialog("Error", "Writing file", "Ok", NULL);
free(buff);
}
fclose(fp);
pfd->modified = False;
MObjectSetText(pfd->modified_label, " ");
/* FreeUndoList(pfd);
*/
}
/*
* This callback handles user's save-as request
*/
void SaveAsCB(MOBJECT p, void *od, void *ad)
{
char pname[MAXPATHLEN];
MOBJECT shell = (MOBJECT)ad;
FILE_DATA *pfd = (FILE_DATA *)MObjectGetUserData(shell);
if (!MFileSelection("Save File As ...", EXT, pfd->filename, pname, True))
return;
strcpy(pfd->pathname, pname);
strcat(pfd->pathname, pfd->filename);
MObjectSetText(pfd->fname_label, pfd->pathname);
MObjectSetText(shell, pfd->filename);
pfd->mod