• Robert Sprowson's avatar
    Switch from ArcEdit style model to clipboard cut & paste model · 99904b10
    Robert Sprowson authored
    The txt library part of RISC_OSLib was essentially contrary to everything Acorn was telling its developers, to use the global clipboard.
    Additionally, support is added for swap case within a selection.
    txt.h:
     Add a new charoption type 'txt_READONLY' to inform txt that the buffer is notionally read only, this is used to supress 'Paste' in the selection menu when appropriate.
     Correct some typos in the comments.
    txt1.h:
     Kill off modula 2 dummy structure member.
    txtar.h:
     Remove unused function export.
    txtfile.h:
     Rename basicimport to be consistent with the text version of the same function. We use 'import' to denote RAM transfers and 'insert' to denote file/scrap transfers throughout.
    txtmisc.h:
     Redundant internal functions removed.
    txtundo.h:
     Add a new undo operation type 't' for swap case, to avoid polluting the undo buffer with an entire copy of the text where only the case changed.
     Kill off modula 2 double pointer requirement.
    txtedit.h:
     Unused structure member 'selectctl' removed.
    txt.c:
     Kill off modula 2 double pointer requirement.
    txtar.c:
     Refactor message despatch with a switch statement so the save/load/open operations are explicitly checked for, in case the application enables other messages.
    txtedit.c:
     Adopt MOVERWRITE, been enabled since 1988 so is probably good to keep.
     Dynamically generate the Select menu by first sending a clipboard request, and fading Paste if no reply comes back.
     Implement changed mouse selection logic.
     Implement different hotkeys and caret navigation.
     Implement copy and paste/replace operations.
     Implement swap case operation.
    txtfile.c:
     Type corrections and function rename admin.
     Implement copy and paste/replace operation for detokenised BASIC.
    txtmisc.c:
     Supporting functions for clipboard added, supporting functions for ArcEdit removed.
    txtscrap.c:
     Make sure the caret is visible for programmatical zero sized selections.
    txtundo.c:
     Allow suspension of undo during known complex operations, such as import via RAM transmit. This was a longstanding bug where the import buffer was grabbed in ~4k chunks (even if only 1 byte was being transferred) which in turn resulted in a +4000 undo insertion and a -3999 removal, which given the default undo buffer is only 5k would result in it failing the reversibility test, so no undo was possible.
     Now, during a RAM transmit undo is suspended until the total transfer size is known, and only that data is placed in the undo buffer (subject to the same 5k reversibility limit).
     Add new undo type 't' for swap case operation.
    rlibdata.s:
     4 new ints and 1 new BOOL, so RlibSpace increases by 5.
    
    Version 5.85. Tagged as 'RISC_OSLib-5_85'
    99904b10
txtedit 15.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/****************************************************************************
 * This source file was written by Acorn Computers Limited. It is part of   *
 * the RISCOS library for writing applications in C for RISC OS. It may be  *
 * used freely in the creation of programs for Archimedes. It should be     *
 * used with Acorn's C Compiler Release 3 or later.                         *
 *                                                                          *
 ***************************************************************************/

/*
 * Title: txtedit.h
 * Purpose: Text editing facilities.
 *
 */

# ifndef __txtedit_h
# define __txtedit_h

# ifndef __txt_h
# include "txt.h"
# endif

# ifndef __typdat_h
# include "typdat.h"
# endif

#ifndef __menu_h
#include "menu.h"
#endif

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif

/****************************** DATA TYPES *********************************/

typedef enum
  {
    txtedit_CHARSEL = 1, txtedit_WORDSEL = 2, txtedit_LINESEL = 4

  } txtedit_seltype;

typedef struct txtedit_state
  {
    txt             t;
    txt_marker      selpivot;       /* used in mouse op calculations */
    txtedit_seltype seltype;        /* used in mouse op calculations */
    int             selectrecent;   /* used in mouse op calculations */
#if FALSE
    int             selectctl;      /* used in mouse op calculations */
#endif
    char            filename[256];
    typdat          ty;
    struct txtedit_state *next;     /* chain of all of them. */
    BOOL            overwrite;
    BOOL            wordtab;
    BOOL            wordwrap;
  } txtedit_state;

typedef BOOL (*txtedit_update_handler)(char *, txtedit_state *, void *);
typedef void (*txtedit_close_handler)(char *, txtedit_state *, void *);
typedef BOOL (*txtedit_save_handler)(char *, txtedit_state *, void *);
typedef void (*txtedit_shutdown_handler)(void *);
typedef void (*txtedit_undofail_handler)(char *, txtedit_state *, void *);
typedef void (*txtedit_open_handler)(char *, txtedit_state *, void *);

/**************************** INTERFACE FUNCTIONS *************************/


/* --------------------------- txtedit_install -----------------------------
 * Description:   Installs an event handler for the txt t, thus making it
 *                an editable text.
 *
 * Parameters:    txt t -- the text object (created via txt_new)
 * Returns:       A pointer to the resulting txtedit_state.
 * Other Info:    none.
 *
 */

txtedit_state *txtedit_install(txt t);


/* ----------------------------- txtedit_new -------------------------------
 * Description:   Creates a new text object, loads the given file into it
 *                and the text can now be edited.
 *
 * Parameters:    char *filename -- the file to be loaded.
 *                int filetype -- filetype to be given if null filename
 * Returns:       a pointer to the txtedit_state for this text.
 * Other Info:    If the file cannot be found, then 0 is returned as a
 *                result, and no text is created. If "filename" is a null
 *                pointer, then an editor window with no given file name
 *                will be constructed. If the file is already being edited,
 *                then a pointer to the existing txtedit_state is returned.
 *
 */

txtedit_state *txtedit_new(char *filename, int filetype);


/* ---------------------------- txtedit_dispose ----------------------------
 * Description:   Destroys the given text being edited.
 *
 * Parameters:    txtedit_state *s -- the text to be destroyed.
 * Returns:       void.
 * Other Info:    Note: this will ask no questions of the user before
 *                destroying the text.
 *
 */

void txtedit_dispose(txtedit_state *s);


/* --------------------------- txtedit_mayquit -----------------------------
 * Description:   Check if we may safely quit editing.
 *
 * Parameters:    void.
 * Returns:       TRUE if we may safely quit, otherwise FALSE.
 * Other Info:    If a text is being edited, then a dialogue box is displayed
 *                asking the user if he really wants to quit.
 *                This calls dboxquery(), and therefore requires the
 *                template "query" as described in dboxquery.h.
 *
 */

BOOL txtedit_mayquit(void);


/* ----------------------------- txtedit_prequit ---------------------------
 * Description:   Deal with a PREQUIT message from the task manager.
 *
 * Parameters:    void.
 * Returns:       void.
 * Other Info:    Calls txtedit_mayquit(), to see if we may quit, if text
 *                is being edited. If user replies that we may quit, then
 *                all texts are disposed of, and this function sends an
 *                acknowledgement to the task manager.
 *
 */

void txtedit_prequit(void);


/* ---------------------------- txtedit_menu -------------------------------
 * Description:   Sets up a menu structure for the text being edited,
 *                tailored to its current state.
 *
 * Parameters:    txtedit_state * s -- the text's current state.
 * Returns:       a pointer to an appropriately formed menu structure
 * Other Info:    The menu created will have the same form as that displayed
 *                when mouse menu button is clicked on an !Edit window.
 *                (For !Edit version 1.00).
 *                Entries in the menu are set according to the supplied
 *                txtedit_state.
 */

menu txtedit_menu(txtedit_state *s);


/*------------------------------ txtedit_menuevent -------------------------
 * Description:   Apply a given menu hit to a given text.
 *
 * Parameters:    txtedit_state *s -- the text to which hit should be applied
 *                char *hit -- a menu hit string.
 * Returns:       void.
 * Other Info:    This can be called from a menu event handler.
 *
 */

void txtedit_menuevent(txtedit_state *s, char *hit);


/* --------------------------- txtedit_doimport ----------------------------
 * Description:   Import data into the specified txtedit object, from a file
 *                of a given type.
 *
 * Parameters:    txtedit_state *s -- the text object
 *                int filetype -- type of the file
 *                int estsize -- file's estimated size.
 * Returns:       TRUE if import completed successfully.
 * Other Info:    none.
 *
 */

BOOL txtedit_doimport(txtedit_state *s, int filetype, int estsize);


/* ------------------------- txtedit_doinsertfile --------------------------
 * Description:   Inserts a named file in a given text object.
 *
 * Parameters:    txtedit_state *s -- the text object
 *                char *filename -- the given file
 *                BOOL replaceifwasnull -- if set to TRUE then the text
 *                                         object will be considred to have
 *                                         come from "filename", ie. window
 *                                         title is updated.
 *
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txtedit_doinsertfile(txtedit_state *s, char *filename, BOOL replaceifwasnull);

/* ------------------------ txtedit_settexttitle --------------------------
 * Description:   Updates the text window titles to reflect the state of
 *                the specified text object
 *
 * Parameters:    txtedit_state *s -- the text object
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txtedit_settexttitle(txtedit_state *s);

/* ------------------------ txtedit_register_update_handler ---------------
 * Description:   Register a handler to be called when a text window is
 *                modified
 *
 * Parameters:    txtedit_handler h -- the handler function
 *                void *handle      -- handle to be passed to the function
 * Returns:       previous handler
 * Other Info:    This routine will be called whenever a window's title bar
 *                is redrawn, and the text in the window has been modified.
 *                Note: this is not just called when the '*' first appears
 *                in a window's title bar, but every time the title bar of a
 *                modified text window is redrawn (eg. when the filename
 *                changes or wordwrap is turned on/off etc).
 *                The handler function will be passed:
 *                       i) the filename for the window title
 *                      ii) the address of this 'txtedit_state'
 *                     iii) the handle registered with this function
 *                If the handler returns FALSE, then the last modification
 *                will be undone.  This is only possible if the modification
 *                is not greater than ~5kb.
 *                Calling with h == 0 removes the handler.
 *
 */

txtedit_update_handler txtedit_register_update_handler(txtedit_update_handler h, void *handle);


/* ------------------------ txtedit_register_save_handler ------------------
 * Description:   Register a handler to be called when a text window is
 *                saved
 *
 * Parameters:    txtedit_handler h -- the handler function
 *                void *handle      -- handle to be passed to the function
 * Returns:       previous handler
 * Other Info:    This routine will be called whenever a text window is saved
 *                to file (NOT via RAM transfer).
 *                The handler function will be passed:
 *                       i) the filename for the window title
 *                      ii) the address of this 'txtedit_state'
 *                     iii) the handle registered with this function
 *                Calling with h == 0 removes the handler.
 *                Returning FALSE from your handler will abort the save
 *                operation.
 *
 */

txtedit_save_handler txtedit_register_save_handler(txtedit_save_handler h,
                                                   void *handle);


/* ------------------------ txtedit_register_close_handler ----------------
 * Description:   Register a handler to be called when a modified text
 *                window is closed
 *
 * Parameters:    txtedit_handler h -- the handler function
 *                void *handle      -- handle to be passed to the function
 * Returns:       previous handler
 * Other Info:    This routine will be called whenever a text
 *                window is closed.
 *                The handler function will be passed:
 *                       i) the filename for the window title
 *                      ii) the address of this 'txtedit_state'
 *                     iii) the handle registered with this function
 *                Calling with h == 0 removes the handler.
 *
 */

txtedit_close_handler txtedit_register_close_handler(txtedit_close_handler h,
                                                     void *handle);


/* ------------------------ txtedit_register_shutdown_handler --------------
 * Description:   Register a handler to be called when txtedit_prequit() is
 *                called.
 *
 * Parameters:    txtedit_handler h -- the handler function
 *                void *handle      -- handle to be passed to the function
 * Returns:       previous handler
 * Other Info:    This routine will be called whenever txtedit_prequit() is
 *                called, and the user answers "yes" when asked if he really
 *                wants to quit edit, or no files have been modified.
 *                The handler function will be passed the handle
 *                registered with this function
 *                Calling with h == 0 removes the handler.
 *
 */

txtedit_shutdown_handler txtedit_register_shutdown_handler(txtedit_shutdown_handler h, void *handle);


/* ------------------------ txtedit_register_undofail_handler --------------
 * Description:   Register a handler to be called when your update_handler
 *                returned FALSE, and the undo buffer overflowed.
 *
 * Parameters:    txtedit_handler h -- the handler function
 *                void *handle      -- handle to be passed to the function
 * Returns:       previous handler
 * Other Info:    This will be called when the modification made to an
 *                edited file cannot be undone (only in conjunction with
 *                an update handler).
 *                The handler function will be passed:
 *                       i) the filename for the window title
 *                      ii) the address of this 'txtedit_state'
 *                     iii) the handle registered with this function
 *                Calling with h == 0 removes the handler.
 *
 */

txtedit_undofail_handler txtedit_register_undofail_handler(txtedit_undofail_handler h, void *handle);


/* -------------------------- txtedit_register_open_handler -------------------
 * Description:   Register a handler to be called when a new txtedit_state is
 *                created.
 *
 * Parameters:    txtedit_handler h -- the handler function
 *                void *handle      -- handle to be passed to the function
 * Returns:       previous handler
 * Other Info:    The handler function will be passed:
 *                       i) the filename for the window title
 *                      ii) the address of this 'txtedit_state'
 *                     iii) the handle registered with this function
 *                Calling with h == 0 removes the handler.
 *
 */

txtedit_open_handler txtedit_register_open_handler(txtedit_open_handler h, void *handle);


/* ---------------------------- txtedit_getstates --------------------------
 * Description:   Get a pointer to the list of current txtedit_states
 *
 * Parameters:    void.
 * Returns:       Pointer to the list of txtedit_states
 * Other Info:    The txtedit part of RISC_OSlib keeps a list of all
 *                txtedit_states created (via txtedit_new). This function
 *                allows access to this list
 *
 */

txtedit_state *txtedit_getstates(void);

/* ---------------------------- txtedit_setBASICaddresses ------------------
 * Description:   Initialises the internal pointers to BASIC's tokenising
 *                and detokenising routines. This is necessary before the
 *                txtedit module can tokenise and detokenise BASIC.
 *
 * Parameters:    int tokenise   -- the address of BASIC's tokeniser
 *                int detokenise -- the address of BASIC's detokeniser
 * Returns:       void.
 * Other Info:    These two addresses can be obtained from the short BASIC
 *                program inside !Edit, which sets two system variables.
 *
 */

void txtedit_setBASICaddresses(int tokenise, int detokenise);

/* ---------------------------- txtedit_setBASICstrip ----------------------
 * Description:   Sets the internal flag to indicate whether or not line
 *                numbers should be stripped from BASIC files being loaded.
 *
 * Parameters:    BOOL strip -- TRUE if line numbers should be stripped,
 *                              else FALSE
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txtedit_setBASICstrip(BOOL strip);

/* ---------------------------- txtedit_setBASICincrement ------------------
 * Description:   Sets the increment to be used when creating line numbers.
 *
 * Parameters:    int increment
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txtedit_setBASICincrement(int increment);

/* ---------------------------- txtedit_init -------------------------------
 * Description:   Initialise the txtedit module of the library
 *
 * Parameters:    void.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txtedit_init(void);

#endif

/* end txtedit.h */