home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: wx_text.cc
- * Purpose: wxTextWindow implementation
- *
- * wxWindows 1.40
- * Copyright (c) 1993 Artificial Intelligence Applications Institute,
- * The University of Edinburgh
- *
- * Author: Julian Smart
- * Date: 18-4-93
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice, author statement and this permission
- * notice appear in all copies of this software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
- * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
- * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
- * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <windows.h>
- #include <iostream.h>
- #include <fstream.h>
- #include <stdio.h>
-
- #include "common.h"
- #include "wx_main.h"
- #include "wx_text.h"
- #include "wx_event.h"
- #include "wx_utils.h"
- #include "wx_frame.h"
- #include "wx_privt.h"
-
- #ifdef wx_motif
- #include <Xm/Text.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
-
- #ifdef wx_xview
- #include <xview/textsw.h>
- #endif
-
- #ifdef wx_msw
- class wxTextWnd : public wxSubWnd
- {
- public:
- wxWindow *wx_window;
- char **lines;
- int no_lines;
- int current_line;
-
- int cxChar;
- int cyChar;
-
- int cxClient;
- int cyClient;
-
- wxTextWnd(wxWnd *parent, wxWindow *wx_win,
- int x, int y, int width, int height, DWORD style);
- ~wxTextWnd();
-
- void CalcNewSize(int x, int y);
-
- void OnCreate(void);
- BOOL OnPaint(void);
- void OnSize(int x, int y, UINT);
-
- void WriteText(char *text);
-
- };
- #endif
-
- wxTextWindow::wxTextWindow(wxFrame *frame, int x, int y, int width, int height,
- int style)
- {
- file_name = NULL;
-
- #ifdef wx_motif
- textPosition = 0;
- textModified = FALSE;
- int real_y = y;
- Widget textWidget = XmCreateScrolledText(frame->workArea, "text_widget", NULL, 0);
-
- XtVaSetValues(textWidget,
- XmNleftAttachment, XmATTACH_SELF,
- XmNrightAttachment, XmATTACH_SELF,
- XmNtopAttachment, XmATTACH_SELF,
- XmNbottomAttachment, XmATTACH_SELF,
- NULL);
-
- XtVaSetValues(textWidget,
- XmNeditable, True,
- XmNeditMode, XmMULTI_LINE_EDIT,
- NULL);
-
- wxWidgetHashTable->Put((long)textWidget, this);
-
- XtOverrideTranslations(textWidget,
- XtParseTranslationTable("<Configure>: resize()"));
-
- Widget parent = XtParent(textWidget);
- if (x > -1)
- XtVaSetValues(parent,
- XmNleftAttachment, XmATTACH_SELF,
- XmNx, x,
- NULL);
-
- if (y > -1)
- XtVaSetValues(parent,
- XmNtopAttachment, XmATTACH_SELF,
- XmNy, real_y,
- NULL);
-
- if (width > -1)
- XtVaSetValues(parent, XmNwidth, width, NULL);
- if (height > -1)
- XtVaSetValues(parent, XmNheight, height, NULL);
-
- XtManageChild(textWidget);
- handle = (char *)textWidget;
- #endif
- #ifdef wx_xview
- int real_y = frame->y_offset;
- if (y > -1)
- real_y = y + frame->y_offset; // Allow for possible menu bar
-
- Frame x_frame = (Frame)frame->handle;
- Textsw x_textsw = (Textsw)xv_create(x_frame, TEXTSW,
- WIN_CLIENT_DATA, (char *)this, XV_SHOW, FALSE,
- TEXTSW_MEMORY_MAXIMUM, 400000,
- NULL);
- handle = (char *)x_textsw;
- window_parent = frame;
- file_name = NULL;
-
- if (x > -1)
- xv_set(x_textsw, XV_X, x, NULL);
- if (y > -1)
- xv_set(x_textsw, XV_Y, real_y, NULL);
- if (width > -1)
- xv_set(x_textsw, XV_WIDTH, width, NULL);
- if (height > -1)
- xv_set(x_textsw, XV_HEIGHT, height, NULL);
-
- xv_set(x_textsw, XV_SHOW, TRUE, NULL);
- #endif
-
- #ifdef wx_msw
- wxWinType = wxTYPE_XWND;
- wxWnd *cparent = NULL;
- if (frame)
- cparent = (wxWnd *)frame->handle;
-
- DWORD ms_flags = WS_HSCROLL | WS_VSCROLL | WS_CHILD | WS_VISIBLE;
- if (style & wxBORDER)
- ms_flags |= WS_BORDER;
- handle = (char *)new wxTextWnd(cparent, this, x, y, width, height, ms_flags);
-
- #endif
-
- if (frame) frame->AddChild(this);
- window_parent = frame;
- }
-
- wxTextWindow::~wxTextWindow(void)
- {
- #ifdef wx_motif
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
-
- textsw_reset(textsw, 0, 0);
- #endif
- }
-
- Bool wxTextWindow::LoadFile(char *file)
- {
- if (file_name)
- delete file_name;
-
- file_name = copystring(file);
- #ifdef wx_motif
- Widget textWidget = (Widget)handle;
- FILE *fp;
-
- struct stat statb;
- if ((stat(file, &statb) == -1) || (statb.st_mode & S_IFMT) != S_IFREG ||
- !(fp = fopen(file, "r")))
- {
- return FALSE;
- }
- else
- {
- long len = statb.st_size;
- char *text;
- if (!(text = XtMalloc((unsigned)(len+1))))
- {
- fclose(fp);
- return FALSE;
- }
- if (fread(text, sizeof(char), len, fp) != len)
- {}
- fclose(fp);
-
- text[len] = 0;
- XmTextSetString(textWidget, text);
- textPosition = len;
- XtFree(text);
- textModified = FALSE;
- return TRUE;
- }
- #endif
- #ifdef wx_xview
-
- Textsw textsw = (Textsw)handle;
-
- Textsw_status status;
- xv_set(textsw, TEXTSW_STATUS, &status, TEXTSW_FILE, file_name, TEXTSW_FIRST, 0, NULL);
-
- return (status == TEXTSW_STATUS_OKAY);
- #endif
- #ifdef wx_msw
- Clear();
-
- ifstream input(file);
- if (!input.bad())
- {
- wxTextWnd *text_win = (wxTextWnd *)handle;
- text_win->no_lines = 0;
- while (!input.eof())
- {
- Bool eol = FALSE;
- input.getline(wxBuffer, 500);
- text_win->lines[text_win->no_lines] = copystring(wxBuffer);
- text_win->no_lines ++;
- }
- if (text_win->no_lines > 0)
- text_win->current_line = text_win->no_lines - 1;
- else text_win->current_line = 0;
-
-
- RECT rect;
- GetClientRect(text_win->handle, &rect);
- text_win->OnSize(rect.right, rect.bottom, 0);
- InvalidateRgn(text_win->handle, NULL, TRUE);
- UpdateWindow(text_win->handle);
-
- return TRUE;
- }
- return FALSE;
- #endif
- }
-
- // If file is null, try saved file name first
- // Returns TRUE if succeeds.
- Bool wxTextWindow::SaveFile(char *file)
- {
- #ifdef wx_motif
- Widget textWidget = (Widget)handle;
- FILE *fp;
-
- if (!(fp = fopen(file, "w")))
- {
- return FALSE;
- }
- else
- {
- char *text = XmTextGetString(textWidget);
- long len = XmTextGetLastPosition(textWidget);
-
- if (fwrite(text, sizeof(char), len, fp) != len)
- {
- // Did not write whole file
- }
- // Make sure newline terminates the file
- if (text[len-1] != '\n')
- fputc('\n', fp);
-
- fclose(fp);
- XtFree(text);
- textModified = FALSE;
- return TRUE;
- }
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
-
- char *the_file = file;
- if (!file)
- the_file = file_name;
-
- if (the_file)
- return !textsw_store_file(textsw, the_file, 100, 100);
- else
- return FALSE;
- #endif
-
- #ifdef wx_msw
- return 0;
- #endif
- }
-
- void wxTextWindow::WriteText(char *text)
- {
- #ifdef wx_motif
- Widget textWidget = (Widget)handle;
- XmTextInsert(textWidget, textPosition, text);
- textPosition += strlen(text);
- XtVaSetValues(textWidget, XmNcursorPosition, textPosition, NULL);
- XmTextShowPosition(textWidget, textPosition);
- textModified = TRUE;
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
-
- int l = strlen(text);
- char *new_text = new char[l];
- strcpy(new_text, text);
- int i;
-
- // Convert new lines to something the textsw recognises
- for (i = 0; i < l; i++)
- if (new_text[i] == '\n')
- new_text[i] = (char)10;
-
- xv_set(textsw, TEXTSW_INSERTION_POINT, TEXTSW_INFINITY, NULL);
- textsw_insert(textsw, new_text, l);
- delete new_text;
- #endif
- #ifdef wx_msw
- char *the_text = copystring(text); // Necessary in case text points to
- // wxBuffer
-
- wxTextWnd *text_win = (wxTextWnd *)handle;
- if (text_win->no_lines < wxTEXT_MAX_LINES)
- {
- int len = strlen(the_text);
-
- Bool text_end = FALSE;
-
- int i = 0;
- while (!text_end)
- {
- int j = 0;
- Bool eol = FALSE;
- int old_line_length = strlen(text_win->lines[text_win->current_line]);
- strcpy(wxBuffer, text_win->lines[text_win->current_line]);
-
- while (!eol && !text_end)
- {
- if (i == len)
- {
- wxBuffer[j+old_line_length] = 0;
- text_end = TRUE;
- }
- else
- {
- char ch = the_text[i];
-
- if (ch == '\n' || (j+old_line_length) > 490)
- {
- eol = TRUE;
- wxBuffer[j+old_line_length] = 0;
- if ((j + old_line_length) > 490)
- {
- i --; j --;
- }
- }
- else
- {
- wxBuffer[j+old_line_length] = ch;
- }
- i ++;
- j ++;
- }
- }
- delete text_win->lines[text_win->current_line];
- text_win->lines[text_win->current_line] = copystring(wxBuffer);
-
- HDC dc = GetDC(text_win->handle);
- SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
- SetBkColor(dc, GetSysColor(COLOR_WINDOW));
-
- int x = (text_win->cxChar) * (1 - text_win->xscroll_position);
- int y = (text_win->cyChar) * (text_win->current_line - text_win->yscroll_position);
- TextOut(dc, x, y, wxBuffer, strlen(wxBuffer));
- ReleaseDC(text_win->handle, dc);
-
- if (eol)
- {
- text_win->current_line ++;
- text_win->no_lines ++;
- text_win->lines[text_win->current_line] = new char[1];
- text_win->lines[text_win->current_line][0] = 0;
-
- RECT rect;
- GetClientRect(text_win->handle, &rect);
- text_win->CalcNewSize(rect.right, rect.bottom);
-
- if (y >= (rect.bottom - text_win->cyChar))
- text_win->OnVScroll(SB_BOTTOM, 0, NULL);
-
- (void)wxYield();
- }
- }
-
- }
- delete the_text;
- #endif
- }
-
- void wxTextWindow::SetSize(int x, int y, int w, int h)
- {
- #ifdef wx_motif
- Widget textWidget = (Widget)handle;
- int real_y = y;
-
- Widget parent = XtParent(textWidget);
- if (x > -1)
- XtVaSetValues(parent,
- XmNleftAttachment, XmATTACH_SELF,
- XmNx, x,
- NULL);
-
- if (y > -1)
- XtVaSetValues(parent,
- XmNtopAttachment, XmATTACH_SELF,
- XmNy, real_y,
- NULL);
-
- if (w > -1)
- XtVaSetValues(parent, XmNwidth, w, NULL);
- if (h > -1)
- XtVaSetValues(parent, XmNheight, h, NULL);
-
- Dimension yy;
- XtVaGetValues(textWidget, XmNy, &yy, NULL);
- #endif
- #ifdef wx_xview
- int currentX, currentY;
- GetPosition(¤tX, ¤tY);
- if (x == -1)
- x = currentX;
- if (y == -1)
- y = currentY;
-
- int real_y = y;
-
- if (window_parent)
- real_y += ((wxFrame *)window_parent)->y_offset; // Allow for possible menu bar
-
- Xv_opaque object = (Xv_opaque)handle;
- (void)xv_set(object, XV_X, x, XV_Y, real_y, XV_WIDTH, w, XV_HEIGHT, h, NULL);
- #endif
- #ifdef wx_msw
- wxWnd *wnd = (wxWnd *)handle;
- if (wnd)
- MoveWindow(wnd->handle, x, y, w, h, TRUE);
- #endif
- OnSize(w, h);
- }
-
-
- void wxTextWindow::Clear(void)
- {
- #ifdef wx_motif
- XmTextSetString((Widget)handle, "");
- textPosition = 0;
- textModified = FALSE;
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
-
- // textsw_delete(textsw, 0, TEXTSW_INFINITY);
- textsw_reset(textsw, 0, 0);
- #endif
- #ifdef wx_msw
- wxTextWnd *text_win = (wxTextWnd *)handle;
- int i;
- for (i = 0; i < text_win->no_lines; i++)
- {
- delete text_win->lines[i];
- text_win->lines[i] = NULL;
- }
- text_win->lines[0] = new char[1];
- text_win->lines[0][0] = 0;
- text_win->no_lines = 1;
- text_win->current_line = 0;
-
- RECT rect;
- GetClientRect(text_win->handle, &rect);
- text_win->OnSize(rect.right, rect.bottom, 0);
- InvalidateRgn(text_win->handle, NULL, TRUE);
- #endif
- }
-
- Bool wxTextWindow::Modified(void)
- {
- #ifdef wx_motif
- return textModified;
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
- return (xv_get(textsw, TEXTSW_MODIFIED));
- #endif
- #ifdef wx_msw
- return FALSE;
- #endif
- }
-
- // Not clear whether Clear is required as well as DiscardEdits
- void wxTextWindow::DiscardEdits(void)
- {
- #ifdef wx_motif
- XmTextSetString((Widget)handle, "");
- textPosition = 0;
- textModified = FALSE;
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
-
- textsw_reset(textsw, 0, 0);
- #endif
- #ifdef wx_msw
- Clear();
- #endif
- }
-
- char *wxTextWindow::GetContents(void)
- {
- #ifdef wx_motif
- return NULL;
- #endif
- #ifdef wx_xview
- Textsw textsw = (Textsw)handle;
- xv_set(textsw, TEXTSW_INSERTION_POINT, TEXTSW_INFINITY, NULL);
- int last = (int)xv_get(textsw, TEXTSW_INSERTION_POINT);
- char *buf = new char[last];
- xv_get(textsw, TEXTSW_CONTENTS, 0, buf, last);
- buf[last] = 0;
-
- return buf;
- #endif
- #ifdef wx_msw
- return NULL;
- #endif
- }
-
- wxTextWindow& wxTextWindow::operator<<(char *s)
- {
- WriteText(s);
- return *this;
- }
-
- wxTextWindow& wxTextWindow::operator<<(float f)
- {
- static char buf[100];
- sprintf(buf, "%.2f", f);
- WriteText(buf);
- return *this;
- }
-
- wxTextWindow& wxTextWindow::operator<<(double d)
- {
- static char buf[100];
- sprintf(buf, "%.2lf", d);
- WriteText(buf);
- return *this;
- }
-
- wxTextWindow& wxTextWindow::operator<<(int i)
- {
- static char buf[100];
- sprintf(buf, "%i", i);
- WriteText(buf);
- return *this;
- }
-
- wxTextWindow& wxTextWindow::operator<<(long i)
- {
- static char buf[100];
- sprintf(buf, "%ld", i);
- WriteText(buf);
- return *this;
- }
-
- wxTextWindow& wxTextWindow::operator<<(char c)
- {
- char buf[2];
-
- buf[0] = c;
- buf[1] = 0;
- WriteText(buf);
- return *this;
- }
-
- #ifdef wx_msw
- wxTextWnd::wxTextWnd(wxWnd *parent, wxWindow *wx_win,
- int x, int y, int width, int height, DWORD style):
- wxSubWnd(parent, "wxCanvasClass", wx_win, x, y, width, height, style)
- {
- no_lines = 1;
- current_line = 0;
- lines = new char *[wxTEXT_MAX_LINES];
- lines[0] = new char[1];
- lines[0][0] = 0;
-
- OnCreate();
- ShowScrollBar(handle, SB_BOTH, TRUE);
- }
-
- wxTextWnd::~wxTextWnd()
- {
- if (lines)
- {
- int i;
- for (i = 0; i < no_lines; i++)
- {
- delete lines[i];
- lines[i] = NULL;
- }
- delete lines;
- }
- }
-
- BOOL wxTextWnd::OnPaint()
- {
- RECT rect;
- if (GetUpdateRect(handle, &rect, FALSE))
- {
- PAINTSTRUCT ps;
- // Hold a pointer to the dc so long as the OnPaint() message
- // is being processed
- HDC dc = BeginPaint(handle, &ps);
-
- ::SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
- ::SetBkColor(dc, GetSysColor(COLOR_WINDOW));
-
- HBRUSH brush = GetStockObject(WHITE_BRUSH);
- ::FillRect(dc, &rect, brush);
-
- int nStart = yscroll_position;
- int nEnd = min(no_lines, yscroll_position + (rect.bottom/cyChar));
-
- int i;
- int x,y;
- for (i = nStart; i < nEnd; i++)
- {
- x = cxChar * (1 - xscroll_position);
- y = cyChar * (i - yscroll_position);
- TextOut(dc, x, y, lines[i], strlen(lines[i]));
- }
-
- EndPaint(handle, &ps);
- return 0;
- }
- return 1;
- }
-
- void wxTextWnd::OnCreate(void)
- {
- TEXTMETRIC tm;
- HDC dc = GetDC(handle);
- GetTextMetrics(dc, &tm);
- ReleaseDC(handle, dc);
- cxChar = tm.tmAveCharWidth;
- cyChar = tm.tmHeight + tm.tmExternalLeading;
- yscroll_pixels_per_line = cyChar;
- xscroll_pixels_per_line = cxChar;
- xscroll_lines = 300;
- yscroll_lines = 0;
- ReleaseDC(handle, dc);
- }
-
- void wxTextWnd::OnSize(int x, int y, UINT)
- {
- CalcNewSize(x, y);
- InvalidateRgn(handle, NULL, TRUE);
- }
-
- void wxTextWnd::CalcNewSize(int x, int y)
- {
- cxClient = x;
- cyClient = y;
-
- int nMaxWidth = xscroll_lines*xscroll_pixels_per_line;
-
- int nVscrollMax = max(0, (int)(no_lines + 2 - cyClient/cyChar));
- yscroll_position = min(yscroll_position, nVscrollMax);
-
- SetScrollRange(handle, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos(handle, SB_VERT, yscroll_position, TRUE);
-
- int nHscrollMax = max(0, (int)(2 + nMaxWidth - cxClient/cxChar));
- xscroll_position = min(xscroll_position, nHscrollMax);
-
- SetScrollRange(handle, SB_HORZ, 0, nHscrollMax, FALSE);
- SetScrollPos(handle, SB_HORZ, xscroll_position, TRUE);
-
- yscroll_lines = no_lines;
- }
- #endif
-
-