1 /***************************************************************************
3 TextEditor.mcc - Textediting MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2010 by TextEditor.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 TextEditor class Support Site: http://www.sf.net/projects/texteditor-mcc
21 ***************************************************************************/
25 #include <exec/memory.h>
26 #include <libraries/mui.h>
27 #include <clib/alib_protos.h>
28 #include <proto/muimaster.h>
29 #include <proto/intuition.h>
30 #include <proto/diskfont.h>
31 #include <proto/graphics.h>
32 #include <proto/keymap.h>
33 #include <proto/exec.h>
34 #include <proto/dos.h>
36 #include "TextEditor_mcp.h"
41 static struct TextFont
*GetFont(UNUSED
struct InstData
*data
, void *obj
, long attr
)
43 struct TextFont
*font
= NULL
;
48 if(DoMethod(obj
, MUIM_GetConfigItem
, attr
, &setting
) && setting
!= NULL
)
53 fontnameLen
= strlen(setting
)+6;
54 if((fontname
= AllocVec(fontnameLen
, MEMF_SHARED
|MEMF_CLEAR
)) != NULL
)
57 struct TextAttr textAttr
;
59 textAttr
.ta_Name
= fontname
;
60 textAttr
.ta_YSize
= 8;
61 textAttr
.ta_Style
= FS_NORMAL
;
62 textAttr
.ta_Flags
= 0;
64 strlcpy(fontname
, setting
, fontnameLen
);
65 if((sizePtr
= strchr(fontname
, '/')) != NULL
)
69 StrToLong(sizePtr
+ 1, &size
);
70 strlcpy(sizePtr
, ".font", fontnameLen
-(sizePtr
-fontname
));
71 textAttr
.ta_YSize
= size
;
74 font
= OpenDiskFont(&textAttr
);
86 static void SetCol(struct InstData
*data
, void *obj
, long item
, ULONG
*storage
, long bit
)
88 struct MUI_PenSpec
*spec
;
92 if(DoMethod(obj
, MUIM_GetConfigItem
, item
, &spec
))
94 *storage
= MUI_ObtainPen(muiRenderInfo(obj
), spec
, 0L);
95 data
->allocatedpens
|= 1<<bit
;
98 W(DBF_STARTUP
, "couldn't get config item: 0x%08lx", item
);
105 void InitConfig(struct InstData
*data
, Object
*obj
)
108 BOOL loadDefaultKeys
= FALSE
;
112 data
->allocatedpens
= 0;
113 data
->textcolor
= _pens(obj
)[MPEN_TEXT
];
114 data
->backgroundcolor
= _pens(obj
)[MPEN_BACKGROUND
];
115 data
->highlightcolor
= _pens(obj
)[MPEN_SHINE
];
116 data
->cursorcolor
= _pens(obj
)[MPEN_SHINE
];
117 data
->cursortextcolor
= _pens(obj
)[MPEN_TEXT
];
118 data
->markedcolor
= _pens(obj
)[MPEN_FILL
];
119 data
->separatorshine
= _pens(obj
)[MPEN_HALFSHINE
];
120 data
->separatorshadow
= _pens(obj
)[MPEN_HALFSHADOW
];
121 data
->inactivecolor
= _pens(obj
)[MPEN_HALFSHADOW
];
123 SetCol(data
, obj
, MUICFG_TextEditor_TextColor
, &data
->textcolor
, 0);
124 SetCol(data
, obj
, MUICFG_TextEditor_CursorColor
, &data
->cursorcolor
, 1);
125 SetCol(data
, obj
, MUICFG_TextEditor_CursorTextColor
, &data
->cursortextcolor
, 2);
126 SetCol(data
, obj
, MUICFG_TextEditor_HighlightColor
, &data
->highlightcolor
, 3);
127 SetCol(data
, obj
, MUICFG_TextEditor_MarkedColor
, &data
->markedcolor
, 4);
128 SetCol(data
, obj
, MUICFG_TextEditor_SeparatorShine
, &data
->separatorshine
, 5);
129 SetCol(data
, obj
, MUICFG_TextEditor_SeparatorShadow
, &data
->separatorshadow
, 6);
130 SetCol(data
, obj
, MUICFG_TextEditor_InactiveColor
, &data
->inactivecolor
, 7);
132 if(isFlagClear(data
->flags
, FLG_OwnBackground
))
134 LONG background
= MUII_BACKGROUND
;
136 data
->backgroundcolor
= 0;
137 data
->fastbackground
= TRUE
;
139 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_Background
, &setting
) && setting
!= 0)
141 char *bg_setting
= (char *)setting
;
143 if(bg_setting
[0] == '2' && bg_setting
[1] == ':' )
145 struct MUI_PenSpec
*spec
= (struct MUI_PenSpec
*)(bg_setting
+2);
147 data
->backgroundcolor
= MUI_ObtainPen(muiRenderInfo(obj
), spec
, 0L);
148 data
->allocatedpens
|= 1<<8;
150 else if(bg_setting
[0] != '\0')
151 data
->fastbackground
= FALSE
;
153 background
= setting
;
155 set(obj
, MUIA_Background
, background
);
158 data
->fastbackground
= FALSE
;
160 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_TabSize
, &setting
))
162 data
->TabSize
= *(long *)setting
;
163 if(data
->TabSize
> 12)
171 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_CursorWidth
, &setting
))
173 data
->CursorWidth
= *(long *)setting
;
174 if(data
->CursorWidth
> 6)
175 data
->CursorWidth
= 6;
179 data
->CursorWidth
= 6;
182 data
->normalfont
= GetFont(data
, obj
, MUICFG_TextEditor_NormalFont
);
183 data
->fixedfont
= GetFont(data
, obj
, MUICFG_TextEditor_FixedFont
);
184 data
->font
= (data
->use_fixedfont
== TRUE
) ? data
->fixedfont
: data
->normalfont
;
186 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_BlockQual
, &setting
))
188 switch(*(LONG
*)setting
)
191 data
->blockqual
= IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
;
194 data
->blockqual
= IEQUALIFIER_CONTROL
;
197 data
->blockqual
= IEQUALIFIER_LALT
| IEQUALIFIER_RALT
;
204 else data
->blockqual
= IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
;
206 data
->BlinkSpeed
= FALSE
;
207 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_BlinkSpeed
, &setting
))
211 data
->blinkhandler
.ihn_Object
= obj
;
212 data
->blinkhandler
.ihn_Millis
= *(LONG
*)setting
*25;
213 data
->blinkhandler
.ihn_Method
= MUIM_TextEditor_ToggleCursor
;
214 data
->blinkhandler
.ihn_Flags
= MUIIHNF_TIMER
;
215 data
->BlinkSpeed
= 1;
219 if(isFlagClear(data
->flags
, FLG_OwnFrame
))
222 if(MUIMasterBase
->lib_Version
>= 20)
223 set(obj
, MUIA_Frame
, DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_Frame
, &setting
) ? (STRPTR
)setting
: (STRPTR
)"302200");
224 else set(obj
, MUIA_Frame
, MUIV_Frame_String
);
226 set(obj
, MUIA_Frame
, MUIV_Frame_String
);
227 // #warning "FIXME AROS/Zune: does not support things like MUIA_Frame, "302200"!"
231 data
->TypeAndSpell
= FALSE
;
232 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_TypeNSpell
, &setting
))
235 data
->TypeAndSpell
= TRUE
;
236 set(obj
, MUIA_TextEditor_TypeAndSpell
, data
->TypeAndSpell
);
239 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_CheckWord
, &setting
))
242 setFlag(data
->flags
, FLG_CheckWords
);
244 clearFlag(data
->flags
, FLG_CheckWords
);
247 data
->Flow
= data
->actualline
->line
.Flow
;
248 data
->Pen
= GetColor(data
->CPos_X
, data
->actualline
);
250 if(isFlagClear(data
->flags
, FLG_FirstInit
))
252 setFlag(data
->flags
, FLG_FirstInit
);
253 data
->NoNotify
= TRUE
;
255 MUIA_FillArea
, FALSE
,
256 MUIA_TextEditor_Flow
, data
->Flow
,
257 MUIA_TextEditor_Pen
, data
->Pen
,
258 MUIA_TextEditor_AreaMarked
, FALSE
,
259 MUIA_TextEditor_UndoAvailable
, FALSE
,
260 MUIA_TextEditor_RedoAvailable
, FALSE
,
261 MUIA_TextEditor_HasChanged
, FALSE
,
264 data
->NoNotify
= FALSE
;
272 setting
= (long)&lort
;
273 DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_Smooth
, &setting
);
274 if(data
->slider
!= NULL
)
276 set(data
->slider
, MUIA_Prop_DoSmooth
, *(long *)setting
);
280 data
->selectPointer
= TRUE
;
281 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_SelectPointer
, &setting
))
283 if(*(long *)setting
== 0)
284 data
->selectPointer
= FALSE
;
287 data
->inactiveCursor
= TRUE
;
288 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_InactiveCursor
, &setting
))
290 if(*(long *)setting
== 0)
291 data
->inactiveCursor
= FALSE
;
297 // get the saved undo size only if it was not yet set by the application
298 if(data
->userUndoBufferSize
== FALSE
)
302 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_UndoSize
, &setting
))
304 undoSteps
= *(long *)setting
;
306 // constrain the number of undo levels only if undo is enabled
307 if(undoSteps
!= 0 && undoSteps
< 20)
312 undoSteps
= data
->maxUndoSteps
;
314 ResizeUndoBuffer(data
, undoSteps
);
317 data
->LookupSpawn
= 0;
318 data
->LookupCmd
= "";
319 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_LookupCmd
, &setting
))
321 data
->LookupSpawn
= (short) *(ULONG
*)setting
;
322 data
->LookupCmd
= (char *)setting
+4;
325 data
->SuggestSpawn
= 1;
326 data
->SuggestCmd
= "\"Open('f', 'T:Matches', 'W');WriteLn('f', '%s');Close('f')\"";
327 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_SuggestCmd
, &setting
))
329 data
->SuggestSpawn
= (short) *(ULONG
*)setting
;
330 data
->SuggestCmd
= (char *)setting
+4;
333 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_ConfigVersion
, &setting
))
335 if(*(ULONG
*)setting
!= CONFIG_VERSION
)
337 if(MUI_Request(_app(obj
), NULL
, 0L, "TextEditor.mcc Warning", "Ok|Abort",
338 "Your current keybindings setup of TextEditor.mcc\n"
339 "was found to be incompatible with this version of\n"
342 "The keybindings of this object will be temporarly\n"
343 "set to the default. Please visit the MUI preferences\n"
344 "of TextEditor.mcc to permanently update the keybindings.") == 1)
346 loadDefaultKeys
= TRUE
;
352 struct te_key
*userkeys
;
357 if(loadDefaultKeys
== TRUE
|| !DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_TextEditor_Keybindings
, &setting
) || setting
== 0)
358 userkeys
= (struct te_key
*)default_keybindings
;
360 userkeys
= (struct te_key
*)setting
;
362 while((WORD
)userkeys
[count
].code
!= -1)
365 // now we calculate the memory size
366 size
= (count
+1)*sizeof(struct te_key
);
368 if((data
->RawkeyBindings
= AllocVecPooled(data
->mypool
, size
)) != NULL
)
371 struct te_key
*mykeys
= data
->RawkeyBindings
;
373 memcpy(mykeys
, userkeys
, size
);
375 for(i
=0; i
< count
&& (WORD
)mykeys
[i
].code
!= -1; i
++)
377 struct te_key
*curKey
= &mykeys
[i
];
379 //D(DBF_STARTUP, "checking curKey[%d]: %08lx", i, curKey);
381 if(curKey
->code
>= 500)
384 char code
= curKey
->code
-500;
386 MapANSI(&code
, 1, RAW
, 1, NULL
);
388 curKey
->code
= RAW
[0];
389 curKey
->qual
|= RAW
[1];
391 if(RAW
[0] == 67 && isFlagClear(curKey
->qual
, IEQUALIFIER_NUMERICPAD
))
405 void FreeConfig(struct InstData
*data
, struct MUI_RenderInfo
*mri
)
409 if(data
->RawkeyBindings
!= NULL
)
410 FreeVecPooled(data
->mypool
, data
->RawkeyBindings
);
412 if(data
->allocatedpens
& (1<<0))
413 MUI_ReleasePen(mri
, data
->textcolor
);
414 if(data
->allocatedpens
& (1<<1))
415 MUI_ReleasePen(mri
, data
->cursorcolor
);
416 if(data
->allocatedpens
& (1<<2))
417 MUI_ReleasePen(mri
, data
->cursortextcolor
);
418 if(data
->allocatedpens
& (1<<3))
419 MUI_ReleasePen(mri
, data
->highlightcolor
);
420 if(data
->allocatedpens
& (1<<4))
421 MUI_ReleasePen(mri
, data
->markedcolor
);
422 if(data
->allocatedpens
& (1<<5))
423 MUI_ReleasePen(mri
, data
->separatorshine
);
424 if(data
->allocatedpens
& (1<<6))
425 MUI_ReleasePen(mri
, data
->separatorshadow
);
426 if(data
->allocatedpens
& (1<<7))
427 MUI_ReleasePen(mri
, data
->inactivecolor
);
428 if(data
->allocatedpens
& (1<<8))
429 MUI_ReleasePen(mri
, data
->backgroundcolor
);
431 if(data
->normalfont
!= NULL
)
432 CloseFont(data
->normalfont
);
433 if(data
->fixedfont
!= NULL
)
434 CloseFont(data
->fixedfont
);
436 if(data
->BlinkSpeed
== 2)
438 DoMethod(_app(data
->object
), MUIM_Application_RemInputHandler
, &data
->blinkhandler
);
439 data
->BlinkSpeed
= 1;