This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
fte/view.cpp

736 lines
18 KiB
C++
Raw Permalink Normal View History

/* view.cpp
*
* Copyright (c) 1994-1996, Marko Macek
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
#include "fte.h"
EView *ActiveView = 0;
extern BufferView *BufferList;
EView::EView(EModel *AModel) {
if (ActiveView) {
Prev = ActiveView;
Next = ActiveView->Next;
Prev->Next = this;
Next->Prev = this;
} else
Prev = Next = this;
ActiveView = this;
Model = AModel;
NextView = 0;
Port = 0;
MView = 0;
CurMsg = 0;
if (Model)
Model->CreateViewPort(this);
}
EView::~EView() {
if (Next != this) {
Prev->Next = Next;
Next->Prev = Prev;
if (ActiveView == this)
ActiveView = Next;
} else
ActiveView = 0;
if (MView)
MView->View = 0;
if (Model)
Model->RemoveView(this);
if (Port)
delete Port;
}
int EView::CanQuit() {
if (Model)
return Model->CanQuit();
else
return 1;
}
void EView::FocusChange(int GetFocus) {
if (GetFocus) {
if (Model->View && Model->View->Port)
Model->View->Port->GetPos();
Model->CreateViewPort(this);
} else {
if (Model) {
Model->RemoveView(this);
delete Port;
Port = 0;
if (Model->View && Model->View->Port)
Model->View->Port->StorePos();
}
}
}
void EView::Resize(int Width, int Height) {
if (Port)
Port->Resize(Width, Height);
}
void EView::SetModel(EModel *AModel) {
Model = AModel;
ActiveModel = Model;
}
void EView::SelectModel(EModel *AModel) {
if (Model != AModel) {
if (Model)
FocusChange(0);
SetModel(AModel);
if (Model)
FocusChange(1);
}
}
void EView::SwitchToModel(EModel *AModel) {
if (Model != AModel) {
if (Model)
FocusChange(0);
AModel->Prev->Next = AModel->Next;
AModel->Next->Prev = AModel->Prev;
if (Model) {
AModel->Next = Model;
AModel->Prev = Model->Prev;
AModel->Prev->Next = AModel;
Model->Prev = AModel;
} else {
AModel->Next = AModel->Prev = AModel;
}
SetModel(AModel);
if (Model)
FocusChange(1);
}
}
void EView::Activate(int GotFocus) {
if (Model && Model->View != this && Port) {
Model->SelectView(this);
if (GotFocus) {
Port->StorePos();
} else {
Port->GetPos();
}
Port->RepaintView();
if (GotFocus)
ActiveView = this;
}
}
int EView::GetContext() {
return Model ? Model->GetContext() : 0;
}
EEventMap *EView::GetEventMap() {
return Model ? Model->GetEventMap() : 0;
}
int EView::BeginMacro() {
return Model ? Model->BeginMacro() : 0;
}
int EView::ExecCommand(int Command, ExState &State) {
switch (Command) {
case ExSwitchTo: return SwitchTo(State);
case ExFilePrev: return FilePrev();
case ExFileNext: return FileNext();
case ExFileLast: return FileLast();
case ExFileOpen: return FileOpen(State);
case ExFileOpenInMode: return FileOpenInMode(State);
case ExFileSaveAll: return FileSaveAll();
case ExListRoutines:
#ifdef CONFIG_OBJ_ROUTINE
return ViewRoutines(State);
#else
return ErFAIL;
#endif
case ExDirOpen:
#ifdef CONFIG_OBJ_DIRECTORY
return DirOpen(State);
#else
return ErFAIL;
#endif
#ifdef CONFIG_OBJ_MESSAGES
case ExViewMessages: return ViewMessages(State);
case ExCompile: return Compile(State);
case ExRunCompiler: return RunCompiler(State);
case ExCompilePrevError: return CompilePrevError(State);
case ExCompileNextError: return CompileNextError(State);
#else
case ExViewMessages: return ErFAIL;
case ExCompile: return ErFAIL;
case ExCompilePrevError: return ErFAIL;
case ExCompileNextError: return ErFAIL;
#endif
case ExViewBuffers: return ViewBuffers(State);
case ExShowKey: return ShowKey(State);
case ExToggleSysClipboard: return ToggleSysClipboard(State);
case ExSetPrintDevice: return SetPrintDevice(State);
case ExShowVersion: return ShowVersion();
case ExViewModeMap: return ViewModeMap(State);
case ExClearMessages: return ClearMessages();
#ifdef CONFIG_TAGS
case ExTagNext: return TagNext(this);
case ExTagPrev: return TagPrev(this);
case ExTagPop: return TagPop(this);
case ExTagClear: TagClear(); return 1;
case ExTagLoad: return TagLoad(State);
#endif
case ExShowHelp: return SysShowHelp(State, 0);
case ExConfigRecompile: return ConfigRecompile(State);
case ExRemoveGlobalBookmark:return RemoveGlobalBookmark(State);
case ExGotoGlobalBookmark: return GotoGlobalBookmark(State);
case ExPopGlobalBookmark: return PopGlobalBookmark();
}
return Model ? Model->ExecCommand(Command, State) : 0;
}
void EView::HandleEvent(TEvent &Event) {
if (Model)
Model->HandleEvent(Event);
if (Port)
Port->HandleEvent(Event);
if (Event.What == evCommand) {
switch (Event.Msg.Command) {
case cmDroppedFile:
{
char *file = (char *)Event.Msg.Param2;
#ifdef CONFIG_OBJ_DIRECTORY
if (IsDirectory(file))
OpenDir(file);
#endif
MultiFileLoad(0, file, NULL, this);
}
break;
}
}
}
void EView::UpdateView() {
if (Port)
Port->UpdateView();
}
void EView::RepaintView() {
if (Port)
Port->RepaintView();
}
void EView::UpdateStatus() {
if (Port)
Port->UpdateStatus();
}
void EView::RepaintStatus() {
if (Port)
Port->RepaintStatus();
}
void EView::DeleteModel(EModel *M) {
EView *V;
EModel *M1;
char s[256];
if (M == 0)
return;
M->GetName(s, sizeof(s));
Msg(S_INFO, "Closing %s.", s);
V = ActiveView = this;
while (V) {
M1 = V->Model;
if (M1 == M) {
if (M->Next != M)
V->SelectModel(M->Next);
else
V->SelectModel(0);
}
V = V->Next;
if (V == ActiveView)
break;
}
delete M;
SetMsg(0);
return;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
int EView::FilePrev() {
if (Model) {
SelectModel(Model->Prev);
return 1;
}
return 0;
}
int EView::FileNext() {
if (Model) {
SelectModel(Model->Next);
return 1;
}
return 0;
}
int EView::FileLast() {
if (Model) {
SwitchToModel(Model->Next);
return 1;
}
return 0;
}
int EView::SwitchTo(ExState &State) {
EModel *M;
int No;
if (State.GetIntParam(this, &No) == 0) {
char str[10] = "";
if (MView->Win->GetStr("Obj.Number", sizeof(str), str, 0) == 0) return 0;
No = atoi(str);
}
M = Model;
while (M) {
if (M->ModelNo == No) {
SwitchToModel(M);
return 1;
}
M = M->Next;
if (M == Model)
return 0;
}
return 0;
}
int EView::FileSaveAll() {
EModel *M = Model;
while (M) {
if (M->GetContext() == CONTEXT_FILE) {
EBuffer *B = (EBuffer *)M;
if (B->Modified) {
SwitchToModel(B);
if (B->Save() == 0) return 0;
}
}
M = M->Next;
if (M == Model) break;
}
return 1;
}
int EView::FileOpen(ExState &State) {
char FName[MAXPATH];
if (State.GetStrParam(this, FName, sizeof(FName)) == 0) {
if (GetDefaultDirectory(Model, FName, sizeof(FName)) == 0)
return 0;
if (MView->Win->GetFile("Open file", sizeof(FName), FName, HIST_PATH, GF_OPEN) == 0) return 0;
}
if( strlen( FName ) == 0 ) return 0;
#ifdef CONFIG_OBJ_DIRECTORY
if (IsDirectory(FName))
return OpenDir(FName);
#endif
return MultiFileLoad(0, FName, NULL, this);
}
int EView::FileOpenInMode(ExState &State) {
char Mode[32] = "";
char FName[MAXPATH];
if (State.GetStrParam(this, Mode, sizeof(Mode)) == 0)
if (MView->Win->GetStr("Mode", sizeof(Mode), Mode, HIST_SETUP) != 1) return 0;
if (FindMode(Mode) == 0) {
MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Invalid mode '%s'", Mode);
return 0;
}
if (GetDefaultDirectory(Model, FName, sizeof(FName)) == 0)
return 0;
if (State.GetStrParam(this, FName, sizeof(FName)) == 0)
if (MView->Win->GetFile("Open file", sizeof(FName), FName, HIST_PATH, GF_OPEN) == 0) return 0;
#ifdef CONFIG_OBJ_DIRECTORY
{
int l = strlen(FName);
if (l > 1 && ISSLASH(FName[l - 1]))
return OpenDir(FName);
}
#endif
if( strlen( FName ) == 0 ) return 0;
return MultiFileLoad(0, FName, Mode, this);
}
int EView::SetPrintDevice(ExState &State) {
char Dev[MAXPATH];
strcpy(Dev, PrintDevice);
if (State.GetStrParam(this, Dev, sizeof(Dev)) == 0)
if (MView->Win->GetStr("Print to", sizeof(Dev), Dev, HIST_SETUP) == 0) return 0;
strcpy(PrintDevice, Dev);
return 1;
}
int EView::ToggleSysClipboard(ExState &/*State*/) {
SystemClipboard = SystemClipboard ? 0 : 1;
Msg(S_INFO, "SysClipboard is now %s.", SystemClipboard ? "ON" : "OFF");
return 1;
}
int EView::ShowKey(ExState &/*State*/) {
char buf[100];
KeySel ks;
ks.Mask = 0;
ks.Key = MView->Win->GetChar(0);
GetKeyName(buf, ks);
Msg(S_INFO, "Key: '%s' - '%8X'", buf, ks.Key);
return 1;
}
void EView::Msg(int level, const char *s, ...) {
va_list ap;
va_start(ap, s);
vsprintf(msgbuftmp, s, ap);
va_end(ap);
if (level != S_BUSY)
SetMsg(msgbuftmp);
}
void EView::SetMsg(char *Msg) {
if (CurMsg)
free(CurMsg);
CurMsg = 0;
if (Msg && strlen(Msg))
CurMsg = strdup(Msg);
if (CurMsg && Msg && MView) {
TDrawBuffer B;
char SColor;
int Cols, Rows;
MView->ConQuerySize(&Cols, &Rows);
if (MView->IsActive())
SColor = hcStatus_Active;
else
SColor = hcStatus_Normal;
MoveChar(B, 0, Cols, ' ', SColor, Cols);
MoveStr(B, 0, Cols, CurMsg, SColor, Cols);
if (MView->Win->GetStatusContext() == MView)
MView->ConPutBox(0, Rows - 1, Cols, 1, B);
//printf("%s\n", Msg);
}
}
int EView::ViewBuffers(ExState &/*State*/) {
if (BufferList == 0) {
BufferList = new BufferView(0, &ActiveModel);
SwitchToModel(BufferList);
} else {
BufferList->UpdateList();
BufferList->Row = 1;
SwitchToModel(BufferList);
return 1;
}
return 0;
}
#ifdef CONFIG_OBJ_ROUTINE
int EView::ViewRoutines(ExState &/*State*/) {
//int rc = 1;
//RoutineView *routines;
EModel *M;
EBuffer *Buffer;
M = Model;
if (M->GetContext() != CONTEXT_FILE)
return 0;
Buffer = (EBuffer *)M;
if (Buffer->Routines == 0) {
if (BFS(Buffer, BFS_RoutineRegexp) == 0) {
MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "No routine regexp.");
return 0;
}
Buffer->Routines = new RoutineView(0, &ActiveModel, Buffer);
if (Buffer->Routines == 0)
return 0;
} else {
Buffer->Routines->UpdateList();
}
SwitchToModel(Buffer->Routines);
return 1;
}
#endif
#ifdef CONFIG_OBJ_DIRECTORY
int EView::DirOpen(ExState &State) {
char Path[MAXPATH];
if (State.GetStrParam(this, Path, sizeof(Path)) == 0)
if (GetDefaultDirectory(Model, Path, sizeof(Path)) == 0)
return 0;
return OpenDir(Path);
}
int EView::OpenDir(char *Path) {
char XPath[MAXPATH];
EDirectory *dir = 0;
if (ExpandPath(Path, XPath) == -1)
return 0;
{
EModel *x = Model;
while (x) {
if (x->GetContext() == CONTEXT_DIRECTORY) {
if (filecmp(((EDirectory *)x)->Path, XPath) == 0)
{
dir = (EDirectory *)x;
break;
}
}
x = x->Next;
if (x == Model)
break;
}
}
if (dir == 0)
dir = new EDirectory(0, &ActiveModel, XPath);
SelectModel(dir);
return 1;
}
#endif
#ifdef CONFIG_OBJ_MESSAGES
int EView::Compile(ExState &State) {
static char Cmd[256] = "";
char Command[256] = "";
if (CompilerMsgs != 0 && CompilerMsgs->Running) {
Msg(S_INFO, "Already running...");
return 0;
}
if (State.GetStrParam(this, Command, sizeof(Command)) == 0) {
if (Model->GetContext() == CONTEXT_FILE) {
EBuffer *B = (EBuffer *)Model;
if (BFS(B, BFS_CompileCommand) != 0)
strcpy(Cmd, BFS(B, BFS_CompileCommand));
}
if (Cmd[0] == 0)
strcpy(Cmd, CompileCommand);
if (MView->Win->GetStr("Compile", sizeof(Cmd), Cmd, HIST_COMPILE) == 0) return 0;
strcpy(Command, Cmd);
} else {
if (MView->Win->GetStr("Compile", sizeof(Command), Command, HIST_COMPILE) == 0) return 0;
}
return Compile(Command);
}
int EView::RunCompiler(ExState &State) {
char Command[256] = "";
if (CompilerMsgs != 0 && CompilerMsgs->Running) {
Msg(S_INFO, "Already running...");
return 0;
}
if (State.GetStrParam(this, Command, sizeof(Command)) == 0) {
if (Model->GetContext() == CONTEXT_FILE) {
EBuffer *B = (EBuffer *)Model;
if (BFS(B, BFS_CompileCommand) != 0)
strcpy(Command, BFS(B, BFS_CompileCommand));
}
if (Command[0] == 0)
strcpy(Command, CompileCommand);
}
return Compile(Command);
}
int EView::Compile(char *Command) {
char Dir[MAXPATH] = "";
EMessages *msgs;
if (CompilerMsgs != 0) {
strcpy(Dir, CompilerMsgs->Directory);
CompilerMsgs->RunPipe(Dir, Command);
msgs = CompilerMsgs;
} else {
if (GetDefaultDirectory(Model, Dir, sizeof(Dir)) == 0)
return 0;
msgs = new EMessages(0, &ActiveModel, Dir, Command);
}
SwitchToModel(msgs);
return 1;
}
int EView::ViewMessages(ExState &/*State*/) {
if (CompilerMsgs != 0) {
SwitchToModel(CompilerMsgs);
return 1;
}
return 0;
}
int EView::CompilePrevError(ExState &/*State*/) {
if (CompilerMsgs != 0)
return CompilerMsgs->CompilePrevError(this);
return 0;
}
int EView::CompileNextError(ExState &/*State*/) {
if (CompilerMsgs != 0)
return CompilerMsgs->CompileNextError(this);
return 0;
}
#endif
int EView::ShowVersion() {
MView->Win->Choice(0, "About", 1, "O&K", PROGRAM " " VERSION " " COPYRIGHT);
return 1;
}
int EView::ViewModeMap(ExState &/*State*/) {
if (TheEventMapView != 0)
TheEventMapView->ViewMap(GetEventMap());
else
(void)new EventMapView(0, &ActiveModel, GetEventMap());
if (TheEventMapView != 0)
SwitchToModel(TheEventMapView);
else
return 0;
return 1;
}
int EView::ClearMessages() {
if (CompilerMsgs != 0 && CompilerMsgs->Running) {
Msg(S_INFO, "Running...");
return 0;
}
if (CompilerMsgs != 0) {
CompilerMsgs->FreeErrors();
CompilerMsgs->UpdateList();
}
return 1;
}
#ifdef CONFIG_TAGS
int EView::TagLoad(ExState &State) {
char Tag[MAXPATH];
char FullTag[MAXPATH];
if (ExpandPath("tags", Tag) == -1)
return 0;
if (State.GetStrParam(this, Tag, sizeof(Tag)) == 0)
if (MView->Win->GetFile("Load tags", sizeof(Tag), Tag, HIST_TAGFILES, GF_OPEN) == 0) return 0;
if (ExpandPath(Tag, FullTag) == -1)
return 0;
if (!FileExists(FullTag)) {
Msg(S_INFO, "Tag file '%s' not found.", FullTag);
return 0;
}
return ::TagLoad(FullTag);
}
#endif
int EView::ConfigRecompile(ExState &State) {
if (ConfigSourcePath == 0 || ConfigFileName[0] == 0) {
Msg(S_ERROR, "Cannot recompile (must use external configuration).");
return 0;
}
char command[1024];
strcpy(command, "cfte ");
strcat(command, ConfigSourcePath);
strcat(command, " ");
#ifdef UNIX
if (ExpandPath("~/.fterc", command + strlen(command)) != 0)
return 0;
#else
strcat(command, ConfigFileName);
#endif
return Compile(command);
}
int EView::RemoveGlobalBookmark(ExState &State) {
char name[256] = "";
if (State.GetStrParam(this, name, sizeof(name)) == 0)
if (MView->Win->GetStr("Remove Global Bookmark", sizeof(name), name, HIST_BOOKMARK) == 0) return 0;
if (markIndex.remove(name) == 0) {
Msg(S_ERROR, "Error removing global bookmark %s.", name);
return 0;
}
return 1;
}
int EView::GotoGlobalBookmark(ExState &State) {
char name[256] = "";
if (State.GetStrParam(this, name, sizeof(name)) == 0)
if (MView->Win->GetStr("Goto Global Bookmark", sizeof(name), name, HIST_BOOKMARK) == 0) return 0;
if (markIndex.view(this, name) == 0) {
Msg(S_ERROR, "Error locating global bookmark %s.", name);
return 0;
}
return 1;
}
int EView::PopGlobalBookmark() {
if (markIndex.popMark(this) == 0) {
Msg(S_INFO, "Bookmark stack empty.");
return 0;
}
return 1;
}
int EView::GetStrVar(int var, char *str, int buflen) {
//switch (var) {
//}
return Model->GetStrVar(var, str, buflen);
}
int EView::GetIntVar(int var, int *value) {
//switch (var) {
//}
return Model->GetIntVar(var, value);
}