1 // This is adapted from 'adie', a text editor found
2 // in the FOX library and written by Jeroen van der Zijp.
3
4 #include "config.h"
5 #include "i18n.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/stat.h>
10 #include <sys/wait.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <signal.h>
14
15 #include <fx.h>
16 #include <fxkeys.h>
17 #include <FXPNGIcon.h>
18 #include <FX88591Codec.h>
19 #include <FXUTF16Codec.h>
20
21 #include "xfedefs.h"
22 #include "icons.h"
23 #include "xfeutils.h"
24 #include "startupnotification.h"
25 #include "FileDialog.h"
26 #include "FontDialog.h"
27 #include "MessageBox.h"
28 #include "InputDialog.h"
29 #include "WriteWindow.h"
30 #include "XFileWrite.h"
31
32
33 extern FXbool allowPopupScroll;
34 FXbool save_win_pos;
35
36
37 FXIMPLEMENT_ABSTRACT(FXTextCommand, FXCommand, NULL, 0)
38
39 // Return size of record plus any data kept here
size() const40 FXuint FXTextCommand::size() const
41 {
42 return(sizeof(FXTextCommand)+ndel);
43 }
44
45
46 FXIMPLEMENT_ABSTRACT(FXTextInsert, FXTextCommand, NULL, 0)
47
48 // Insert command
FXTextInsert(FXText * txt,int p,int ni,const char * ins)49 FXTextInsert::FXTextInsert(FXText* txt, int p, int ni, const char* ins) : FXTextCommand(txt, p, 0, ni)
50 {
51 FXMALLOC(&buffer, char, ni);
52 memcpy(buffer, ins, ni);
53 }
54
55
56 // Undo an insert removes the inserted text
undo()57 void FXTextInsert::undo()
58 {
59 text->removeText(pos, nins, true);
60 text->setCursorPos(pos);
61 text->makePositionVisible(pos);
62 }
63
64
65 // Redo an insert inserts the same old text again
redo()66 void FXTextInsert::redo()
67 {
68 text->insertText(pos, buffer, nins, true);
69 text->setCursorPos(pos+nins);
70 text->makePositionVisible(pos+nins);
71 }
72
73
74 FXIMPLEMENT_ABSTRACT(FXTextDelete, FXTextCommand, NULL, 0)
75
76 // Delete command
FXTextDelete(FXText * txt,int p,int nd,const char * del)77 FXTextDelete::FXTextDelete(FXText* txt, int p, int nd, const char* del) : FXTextCommand(txt, p, nd, 0)
78 {
79 FXMALLOC(&buffer, char, nd);
80 memcpy(buffer, del, nd);
81 }
82
83
84 // Undo a delete reinserts the old text
undo()85 void FXTextDelete::undo()
86 {
87 text->insertText(pos, buffer, ndel, true);
88 text->setCursorPos(pos+ndel);
89 text->makePositionVisible(pos+ndel);
90 }
91
92
93 // Redo a delete removes it again
redo()94 void FXTextDelete::redo()
95 {
96 text->removeText(pos, ndel, true);
97 text->setCursorPos(pos);
98 text->makePositionVisible(pos);
99 }
100
101
102 FXIMPLEMENT_ABSTRACT(FXTextReplace, FXTextCommand, NULL, 0)
103
104 // Replace command
FXTextReplace(FXText * txt,int p,int nd,int ni,const char * del,const char * ins)105 FXTextReplace::FXTextReplace(FXText* txt, int p, int nd, int ni, const char* del, const char* ins) : FXTextCommand(txt, p, nd, ni)
106 {
107 FXMALLOC(&buffer, char, nd+ni);
108 memcpy(buffer, del, nd);
109 memcpy(buffer+nd, ins, ni);
110 }
111
112
113 // Undo a replace reinserts the old text
undo()114 void FXTextReplace::undo()
115 {
116 text->replaceText(pos, nins, buffer, ndel, true);
117 text->setCursorPos(pos+ndel);
118 text->makePositionVisible(pos+ndel);
119 }
120
121
122 // Redo a replace reinserts the new text
redo()123 void FXTextReplace::redo()
124 {
125 text->replaceText(pos, ndel, buffer+ndel, nins, true);
126 text->setCursorPos(pos+nins);
127 text->makePositionVisible(pos+nins);
128 }
129
130
131 // Preferences class
132
133 // Map
134 FXDEFMAP(Preferences) PreferencesMap[] =
135 {
136 FXMAPFUNC(SEL_COMMAND, Preferences::ID_ACCEPT, Preferences::onCmdAccept),
137 FXMAPFUNC(SEL_COMMAND, Preferences::ID_CANCEL, Preferences::onCmdCancel),
138 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_BACK, Preferences::onCmdTextBackColor),
139 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_BACK, Preferences::onCmdTextBackColor),
140 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_BACK, Preferences::onUpdTextBackColor),
141 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_FORE, Preferences::onCmdTextForeColor),
142 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_FORE, Preferences::onCmdTextForeColor),
143 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_FORE, Preferences::onUpdTextForeColor),
144 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_SELBACK, Preferences::onCmdTextSelBackColor),
145 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_SELBACK, Preferences::onCmdTextSelBackColor),
146 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_SELBACK, Preferences::onUpdTextSelBackColor),
147 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_SELFORE, Preferences::onCmdTextSelForeColor),
148 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_SELFORE, Preferences::onCmdTextSelForeColor),
149 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_SELFORE, Preferences::onUpdTextSelForeColor),
150 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_HILITEBACK, Preferences::onCmdTextHiliteBackColor),
151 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_HILITEBACK, Preferences::onCmdTextHiliteBackColor),
152 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_HILITEBACK, Preferences::onUpdTextHiliteBackColor),
153 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_HILITEFORE, Preferences::onCmdTextHiliteForeColor),
154 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_HILITEFORE, Preferences::onCmdTextHiliteForeColor),
155 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_HILITEFORE, Preferences::onUpdTextHiliteForeColor),
156 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_CURSOR, Preferences::onCmdTextCursorColor),
157 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_CURSOR, Preferences::onCmdTextCursorColor),
158 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_CURSOR, Preferences::onUpdTextCursorColor),
159 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_NUMBACK, Preferences::onCmdTextBarColor),
160 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_NUMBACK, Preferences::onCmdTextBarColor),
161 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_NUMBACK, Preferences::onUpdTextBarColor),
162 FXMAPFUNC(SEL_COMMAND, Preferences::ID_TEXT_NUMFORE, Preferences::onCmdTextNumberColor),
163 FXMAPFUNC(SEL_CHANGED, Preferences::ID_TEXT_NUMFORE, Preferences::onCmdTextNumberColor),
164 FXMAPFUNC(SEL_UPDATE, Preferences::ID_TEXT_NUMFORE, Preferences::onUpdTextNumberColor),
165 };
166
167 // Object implementation
FXIMPLEMENT(Preferences,DialogBox,PreferencesMap,ARRAYNUMBER (PreferencesMap))168 FXIMPLEMENT(Preferences, DialogBox, PreferencesMap, ARRAYNUMBER(PreferencesMap))
169
170 // Construct
171 Preferences::Preferences(WriteWindow* owner) : DialogBox(owner, _("XFileWrite Preferences"), DECOR_TITLE|DECOR_BORDER|DECOR_MAXIMIZE|DECOR_STRETCHABLE|DECOR_CLOSE)
172 {
173 // Get the editor text widget from the owner
174 editwin = owner;
175 editor = owner->getEditor();
176
177 // Set title
178 setTitle(_("XFileWrite Preferences"));
179
180 // Buttons
181 FXHorizontalFrame* buttons = new FXHorizontalFrame(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X, 0, 0, 0, 0, 10, 10, 5, 5);
182
183 // Contents
184 FXHorizontalFrame* contents = new FXHorizontalFrame(this, LAYOUT_SIDE_TOP|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
185
186 // Accept
187 FXButton* ok = new FXButton(buttons, _("&Accept"), NULL, this, Preferences::ID_ACCEPT, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT|LAYOUT_CENTER_Y, 0, 0, 0, 0, 20, 20);
188 ok->addHotKey(KEY_Return);
189
190 // Cancel
191 new FXButton(buttons, _("&Cancel"), NULL, this, Preferences::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT|LAYOUT_CENTER_Y, 0, 0, 0, 0, 20, 20);
192
193 // Switcher
194 FXTabBook* tabbook = new FXTabBook(contents, NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT);
195
196 // First tab - Editor
197 new FXTabItem(tabbook, _("&Editor"), NULL);
198 FXVerticalFrame* editor = new FXVerticalFrame(tabbook, FRAME_RAISED);
199 FXGroupBox* group = new FXGroupBox(editor, _("Text"), GROUPBOX_TITLE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X);
200 FXMatrix* matrix = new FXMatrix(group, 2, MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
201
202 new FXLabel(matrix, _("Wrap margin:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
203 wrapmargin = new FXTextField(matrix, 10, NULL, 0, TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW, 0, 0, 0, 0, 2, 2, 1, 1);
204 int wrapcols = getApp()->reg().readIntEntry("OPTIONS", "wrapcols", 80);
205 wrapmargin->setText(FXStringVal(wrapcols));
206
207 new FXLabel(matrix, _("Tabulation size:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
208 tabsize = new FXTextField(matrix, 10, NULL, 0, TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW, 0, 0, 0, 0, 2, 2, 1, 1);
209 int tabcols = getApp()->reg().readIntEntry("OPTIONS", "tabcols", 8);
210 tabsize->setText(FXStringVal(tabcols));
211
212 new FXLabel(matrix, _("Strip carriage returns:")+(FXString)" ", NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
213 stripcr = new FXCheckButton(matrix, FXString(" "), NULL, 0, LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW, 0, 0, 0, 0, 0, 0, 0, 0);
214 int stripreturn = getApp()->reg().readIntEntry("OPTIONS", "stripreturn", false);
215 stripcr->setCheck(stripreturn);
216
217 // Second tab - Colors
218 new FXTabItem(tabbook, _("&Colors"), NULL);
219 FXVerticalFrame* colors = new FXVerticalFrame(tabbook, FRAME_RAISED);
220 group = new FXGroupBox(colors, _("Text"), GROUPBOX_TITLE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X);
221 FXMatrix* matrix1 = new FXMatrix(group, 2, MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
222 group = new FXGroupBox(colors, _("Lines"), GROUPBOX_TITLE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X);
223 FXMatrix* matrix2 = new FXMatrix(group, 2, MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
224
225 new FXLabel(matrix1, _("Background:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
226 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_BACK, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
227
228 new FXLabel(matrix1, _("Text:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
229 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_FORE, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
230
231 new FXLabel(matrix1, _("Selected text background:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
232 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_SELBACK, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
233
234 new FXLabel(matrix1, _("Selected text:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
235 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_SELFORE, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
236
237 new FXLabel(matrix1, _("Highlighted text background:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
238 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_HILITEBACK, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
239
240 new FXLabel(matrix1, _("Highlighted text:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
241 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_HILITEFORE, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
242
243 new FXLabel(matrix1, _("Cursor:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
244 new FXColorWell(matrix1, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_CURSOR, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
245
246 new FXLabel(matrix2, _("Line numbers background:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
247 new FXColorWell(matrix2, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_NUMBACK, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
248
249 new FXLabel(matrix2, _("Line numbers foreground:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
250 new FXColorWell(matrix2, FXRGB(0, 0, 0), this, Preferences::ID_TEXT_NUMFORE, FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW, 0, 0, 40, 24);
251
252 // Class variable initializations
253 stripcr_prev = false;
254 textcolor_prev = FXRGB(0, 0, 0);
255 backcolor_prev = FXRGB(0, 0, 0);
256 textcolor_prev = FXRGB(0, 0, 0);
257 backcolor_prev = FXRGB(0, 0, 0);
258 seltextcolor_prev = FXRGB(0, 0, 0);
259 selbackcolor_prev = FXRGB(0, 0, 0);
260 hilitetextcolor_prev = FXRGB(0, 0, 0);
261 hilitebackcolor_prev = FXRGB(0, 0, 0);
262 cursorcolor_prev = FXRGB(0, 0, 0);
263 barcolor_prev = FXRGB(0, 0, 0);
264 numbercolor_prev = FXRGB(0, 0, 0);
265 }
266
267
onCmdAccept(FXObject * o,FXSelector s,void * p)268 long Preferences::onCmdAccept(FXObject* o, FXSelector s, void* p)
269 {
270 // Update preferences to their new values
271
272 editor->setWrapColumns(FXIntVal(wrapmargin->getText()));
273 getApp()->reg().writeIntEntry("OPTIONS", "wrapcols", FXIntVal(wrapmargin->getText()));
274
275 editor->setTabColumns(FXIntVal(tabsize->getText()));
276 getApp()->reg().writeIntEntry("OPTIONS", "tabcols", FXIntVal(tabsize->getText()));
277
278 editor->setTabColumns(FXIntVal(tabsize->getText()));
279 getApp()->reg().writeIntEntry("OPTIONS", "tabcols", FXIntVal(tabsize->getText()));
280
281 editwin->setStripcr(stripcr->getCheck());
282 getApp()->reg().writeIntEntry("OPTIONS", "stripreturn", stripcr->getCheck());
283
284
285 // Finally, update the registry
286 getApp()->reg().write();
287
288 DialogBox::onCmdAccept(o, s, p);
289
290 return(1);
291 }
292
293
onCmdCancel(FXObject * o,FXSelector s,void * p)294 long Preferences::onCmdCancel(FXObject* o, FXSelector s, void* p)
295 {
296 // Reset preferences to their previous values
297
298 // First tab - Editor
299 wrapmargin->setText(wrapmargin_prev);
300 tabsize->setText(tabsize_prev);
301 stripcr->setCheck(stripcr_prev);
302
303 // Second tab - Colors
304 editor->setTextColor(textcolor_prev);
305 editor->setBackColor(backcolor_prev);
306 editor->setSelTextColor(seltextcolor_prev);
307 editor->setSelBackColor(selbackcolor_prev);
308 editor->setHiliteTextColor(hilitetextcolor_prev);
309 editor->setHiliteBackColor(hilitebackcolor_prev);
310 editor->setCursorColor(cursorcolor_prev);
311 editor->setBarColor(barcolor_prev);
312 editor->setNumberColor(numbercolor_prev);
313
314 DialogBox::onCmdCancel(o, s, p);
315 return(1);
316 }
317
318
319 // Execute dialog box modally
execute(FXuint placement)320 FXuint Preferences::execute(FXuint placement)
321 {
322 // Save current preferences to restore them if cancel is pressed
323
324 // First tab - Editor
325 wrapmargin_prev = wrapmargin->getText();
326 tabsize_prev = tabsize->getText();
327 stripcr_prev = stripcr->getCheck();
328
329 // Second tab - Colors
330 textcolor_prev = editor->getTextColor();
331 backcolor_prev = editor->getBackColor();
332 seltextcolor_prev = editor->getSelTextColor();
333 selbackcolor_prev = editor->getSelBackColor();
334 hilitetextcolor_prev = editor->getHiliteTextColor();
335 hilitebackcolor_prev = editor->getHiliteBackColor();
336 cursorcolor_prev = editor->getCursorColor();
337 barcolor_prev = editor->getBarColor();
338 numbercolor_prev = editor->getNumberColor();
339
340 // Display dialog
341 create();
342 show(placement);
343 getApp()->refresh();
344 return(getApp()->runModalFor(this));
345 }
346
347
348 // Change text color
onCmdTextForeColor(FXObject *,FXSelector,void * ptr)349 long Preferences::onCmdTextForeColor(FXObject*, FXSelector, void* ptr)
350 {
351 editor->setTextColor((FXColor)(FXuval)ptr);
352 return(1);
353 }
354
355
356 // Update text color
onUpdTextForeColor(FXObject * sender,FXSelector,void *)357 long Preferences::onUpdTextForeColor(FXObject* sender, FXSelector, void*)
358 {
359 FXColor color = editor->getTextColor();
360
361 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
362 return(1);
363 }
364
365
366 // Change text background color
onCmdTextBackColor(FXObject *,FXSelector,void * ptr)367 long Preferences::onCmdTextBackColor(FXObject*, FXSelector, void* ptr)
368 {
369 editor->setBackColor((FXColor)(FXuval)ptr);
370 return(1);
371 }
372
373
374 // Update background color
onUpdTextBackColor(FXObject * sender,FXSelector,void *)375 long Preferences::onUpdTextBackColor(FXObject* sender, FXSelector, void*)
376 {
377 FXColor color = editor->getBackColor();
378
379 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
380 return(1);
381 }
382
383
384 // Change selected text foreground color
onCmdTextSelForeColor(FXObject *,FXSelector,void * ptr)385 long Preferences::onCmdTextSelForeColor(FXObject*, FXSelector, void* ptr)
386 {
387 editor->setSelTextColor((FXColor)(FXuval)ptr);
388 return(1);
389 }
390
391
392 // Update selected text foregoround color
onUpdTextSelForeColor(FXObject * sender,FXSelector,void *)393 long Preferences::onUpdTextSelForeColor(FXObject* sender, FXSelector, void*)
394 {
395 FXColor color = editor->getSelTextColor();
396
397 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
398 return(1);
399 }
400
401
402 // Change selected text background color
onCmdTextSelBackColor(FXObject *,FXSelector,void * ptr)403 long Preferences::onCmdTextSelBackColor(FXObject*, FXSelector, void* ptr)
404 {
405 editor->setSelBackColor((FXColor)(FXuval)ptr);
406 return(1);
407 }
408
409
410 // Update selected text background color
onUpdTextSelBackColor(FXObject * sender,FXSelector,void *)411 long Preferences::onUpdTextSelBackColor(FXObject* sender, FXSelector, void*)
412 {
413 FXColor color = editor->getSelBackColor();
414
415 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
416 return(1);
417 }
418
419
420 // Change hilight text color
onCmdTextHiliteForeColor(FXObject *,FXSelector,void * ptr)421 long Preferences::onCmdTextHiliteForeColor(FXObject*, FXSelector, void* ptr)
422 {
423 editor->setHiliteTextColor((FXColor)(FXuval)ptr);
424 return(1);
425 }
426
427
428 // Update hilight text color
onUpdTextHiliteForeColor(FXObject * sender,FXSelector,void *)429 long Preferences::onUpdTextHiliteForeColor(FXObject* sender, FXSelector, void*)
430 {
431 FXColor color = editor->getHiliteTextColor();
432
433 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
434 return(1);
435 }
436
437
438 // Change hilight text background color
onCmdTextHiliteBackColor(FXObject *,FXSelector,void * ptr)439 long Preferences::onCmdTextHiliteBackColor(FXObject*, FXSelector, void* ptr)
440 {
441 editor->setHiliteBackColor((FXColor)(FXuval)ptr);
442 return(1);
443 }
444
445
446 // Update hilight text background color
onUpdTextHiliteBackColor(FXObject * sender,FXSelector,void *)447 long Preferences::onUpdTextHiliteBackColor(FXObject* sender, FXSelector, void*)
448 {
449 FXColor color = editor->getHiliteBackColor();
450
451 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
452 return(1);
453 }
454
455
456 // Change cursor color
onCmdTextCursorColor(FXObject *,FXSelector,void * ptr)457 long Preferences::onCmdTextCursorColor(FXObject*, FXSelector, void* ptr)
458 {
459 editor->setCursorColor((FXColor)(FXuval)ptr);
460 return(1);
461 }
462
463
464 // Update cursor color
onUpdTextCursorColor(FXObject * sender,FXSelector,void *)465 long Preferences::onUpdTextCursorColor(FXObject* sender, FXSelector, void*)
466 {
467 FXColor color = editor->getCursorColor();
468
469 sender->handle(sender, FXSEL(SEL_COMMAND, FXWindow::ID_SETINTVALUE), (void*)&color);
470 return(1);
471 }
472
473
474 // Change line numbers background color
onCmdTextBarColor(FXObject *,FXSelector,void * ptr)475 long Preferences::onCmdTextBarColor(FXObject*, FXSelector, void* ptr)
476 {
477 editor->setBarColor((FXColor)(FXuval)ptr);
478 return(1);
479 }
480
481
482 // Update line numbers background color
onUpdTextBarColor(FXObject * sender,FXSelector,void *)483 long Preferences::onUpdTextBarColor(FXObject* sender, FXSelector, void*)
484 {
485 FXColor color = editor->getBarColor();
486
487 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
488 return(1);
489 }
490
491
492 // Change line numbers color
onCmdTextNumberColor(FXObject *,FXSelector,void * ptr)493 long Preferences::onCmdTextNumberColor(FXObject*, FXSelector, void* ptr)
494 {
495 editor->setNumberColor((FXColor)(FXuval)ptr);
496 return(1);
497 }
498
499
500 // Update line numbers color
onUpdTextNumberColor(FXObject * sender,FXSelector,void *)501 long Preferences::onUpdTextNumberColor(FXObject* sender, FXSelector, void*)
502 {
503 FXColor color = editor->getNumberColor();
504
505 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&color);
506 return(1);
507 }
508
509
510 // WriteWindow class
511
512
513 // Map
514 FXDEFMAP(WriteWindow) WriteWindowMap[] =
515 {
516 FXMAPFUNC(SEL_UPDATE, 0, WriteWindow::onUpdateTitle),
517 FXMAPFUNC(SEL_FOCUSIN, 0, WriteWindow::onFocusIn),
518 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_ABOUT, WriteWindow::onCmdAbout),
519 FXMAPFUNC(SEL_SIGNAL, WriteWindow::ID_HARVEST, WriteWindow::onSigHarvest),
520 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_NEW, WriteWindow::onCmdNew),
521 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_OPEN, WriteWindow::onCmdOpen),
522 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_OPEN_RECENT, WriteWindow::onCmdOpenRecent),
523 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_SAVE, WriteWindow::onCmdSave),
524 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_SAVEAS, WriteWindow::onCmdSaveAs),
525 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_FONT, WriteWindow::onCmdFont),
526 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_PRINT, WriteWindow::onCmdPrint),
527 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_TOGGLE_WRAP, WriteWindow::onUpdWrap),
528 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_TOGGLE_WRAP, WriteWindow::onCmdWrap),
529 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_TOGGLE_LINES_NUM, WriteWindow::onCmdLinesNum),
530 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_TOGGLE_LINES_NUM, WriteWindow::onUpdLinesNum),
531 FXMAPFUNC(SEL_INSERTED, WriteWindow::ID_TEXT, WriteWindow::onTextInserted),
532 FXMAPFUNC(SEL_REPLACED, WriteWindow::ID_TEXT, WriteWindow::onTextReplaced),
533 FXMAPFUNC(SEL_DELETED, WriteWindow::ID_TEXT, WriteWindow::onTextDeleted),
534 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, WriteWindow::ID_TEXT, WriteWindow::onTextRightMouse),
535 FXMAPFUNC(SEL_DND_MOTION, WriteWindow::ID_TEXT, WriteWindow::onEditDNDMotion),
536 FXMAPFUNC(SEL_DND_DROP, WriteWindow::ID_TEXT, WriteWindow::onEditDNDDrop),
537 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_OVERSTRIKE, WriteWindow::onUpdOverstrike),
538 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_NUM_ROWS, WriteWindow::onUpdNumRows),
539 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_PREFERENCES, WriteWindow::onCmdMorePrefs),
540 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_SEARCH, WriteWindow::onCmdSearch),
541 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_REPLACE, WriteWindow::onCmdReplace),
542 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_SEARCH_FORW_SEL, WriteWindow::onCmdSearchSel),
543 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_SEARCH_BACK_SEL, WriteWindow::onCmdSearchSel),
544 FXMAPFUNC(SEL_COMMAND, WriteWindow::ID_GOTO_LINE, WriteWindow::onCmdGotoLine),
545 FXMAPFUNCS(SEL_UPDATE, WriteWindow::ID_WINDOW_1, WriteWindow::ID_WINDOW_50, WriteWindow::onUpdWindow),
546 FXMAPFUNCS(SEL_COMMAND, WriteWindow::ID_WINDOW_1, WriteWindow::ID_WINDOW_50, WriteWindow::onCmdWindow),
547 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_SAVE, WriteWindow::onUpdSave),
548 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_SAVEAS, WriteWindow::onUpdReadOnly),
549 FXMAPFUNC(SEL_UPDATE, WriteWindow::ID_REPLACE, WriteWindow::onUpdReadOnly),
550 };
551
552
553 // Object implementation
FXIMPLEMENT(WriteWindow,FXMainWindow,WriteWindowMap,ARRAYNUMBER (WriteWindowMap))554 FXIMPLEMENT(WriteWindow, FXMainWindow, WriteWindowMap, ARRAYNUMBER(WriteWindowMap))
555
556 // Make some windows
557 WriteWindow::WriteWindow(XFileWrite* a, const FXString& file, const FXbool _readonly) : FXMainWindow(a, "XFileWrite", NULL, NULL, DECOR_ALL), mrufiles(a)
558 {
559 FXHotKey hotkey;
560 FXString key;
561
562 // Add to list of windows
563 getApp()->windowlist.append(this);
564
565 // Default font
566 font = NULL;
567
568 // Application icons
569 setIcon(xfwicon);
570
571 // Status bar
572 statusbar = new FXStatusBar(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER|FRAME_RAISED);
573
574 // Make menu bar
575 menubar = new FXMenuBar(this, LAYOUT_DOCK_NEXT|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_RAISED);
576
577 // Sites where to dock
578 FXDockSite* topdock = new FXDockSite(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
579 new FXDockSite(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X);
580 new FXDockSite(this, LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y);
581 new FXDockSite(this, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y);
582
583 // Toolbar
584 dragshell = new FXToolBarShell(this, FRAME_RAISED);
585 toolbar = new FXToolBar(topdock, dragshell, LAYOUT_DOCK_NEXT|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED);
586 new FXToolBarGrip(toolbar, toolbar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
587
588 // File menu
589 filemenu = new FXMenuPane(this);
590 new FXMenuTitle(menubar, _("&File"), NULL, filemenu);
591
592 // Edit Menu
593 editmenu = new FXMenuPane(this);
594 new FXMenuTitle(menubar, _("&Edit"), NULL, editmenu);
595
596 // View menu
597 viewmenu = new FXMenuPane(this);
598 new FXMenuTitle(menubar, _("&View"), NULL, viewmenu);
599
600 // Search Menu
601 searchmenu = new FXMenuPane(this);
602 new FXMenuTitle(menubar, _("&Search"), NULL, searchmenu);
603
604 // Preferences Menu
605 prefsmenu = new FXMenuPane(this);
606 new FXMenuTitle(menubar, _("&Preferences"), NULL, prefsmenu);
607
608 // Window menu
609 windowmenu = new FXMenuPane(this);
610 new FXMenuTitle(menubar, _("&Window"), NULL, windowmenu);
611
612 // Help menu
613 helpmenu = new FXMenuPane(this);
614 new FXMenuTitle(menubar, _("&Help"), NULL, helpmenu, LAYOUT_LEFT);
615
616 // Make editor window
617 FXHorizontalFrame* textbox = new FXHorizontalFrame(this, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
618 editor = new FXText(textbox, this, ID_TEXT, LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_SHOWACTIVE);
619 editor->setHiliteMatchTime(2000);
620 editor->setTextStyle(editor->getTextStyle()|TEXT_FIXEDWRAP);
621 editor->setTextStyle(editor->getTextStyle()&~TEXT_NO_TABS);
622 editor->setScrollStyle(editor->getScrollStyle()&~SCROLLERS_DONT_TRACK);
623 editor->setTextStyle(editor->getTextStyle()&~TEXT_SHOWACTIVE);
624 editor->setMarginLeft(10);
625
626 // Read only
627 readonly = _readonly;
628 if (readonly)
629 {
630 editor->setTextStyle(editor->getTextStyle()|TEXT_READONLY);
631 }
632
633 // Show insert mode in status bar
634 FXLabel* overstrike = new FXLabel(statusbar, FXString::null, NULL, FRAME_SUNKEN|LAYOUT_RIGHT|LAYOUT_CENTER_Y, 0, 0, 0, 0, 2, 2, 1, 1);
635 overstrike->setTarget(this);
636 overstrike->setSelector(ID_OVERSTRIKE);
637
638 // Show size of text in status bar
639 FXTextField* numchars = new FXTextField(statusbar, 7, this, ID_NUM_ROWS, TEXTFIELD_READONLY|FRAME_SUNKEN|JUSTIFY_RIGHT|LAYOUT_RIGHT|LAYOUT_CENTER_Y, 0, 0, 0, 0, 2, 2, 1, 1);
640 numchars->setBackColor(statusbar->getBackColor());
641
642 // Caption before number
643 new FXLabel(statusbar, _(" Lines:"), NULL, LAYOUT_RIGHT|LAYOUT_CENTER_Y);
644
645 // Show column number in status bar
646 FXTextField* columnno = new FXTextField(statusbar, 7, editor, FXText::ID_CURSOR_COLUMN, FRAME_SUNKEN|JUSTIFY_RIGHT|LAYOUT_RIGHT|LAYOUT_CENTER_Y, 0, 0, 0, 0, 2, 2, 1, 1);
647 columnno->setBackColor(statusbar->getBackColor());
648
649 // Caption before number
650 new FXLabel(statusbar, _(" Col:"), NULL, LAYOUT_RIGHT|LAYOUT_CENTER_Y);
651
652 // Show line number in status bar
653 FXTextField* rowno = new FXTextField(statusbar, 7, editor, FXText::ID_CURSOR_ROW, FRAME_SUNKEN|JUSTIFY_RIGHT|LAYOUT_RIGHT|LAYOUT_CENTER_Y, 0, 0, 0, 0, 2, 2, 1, 1);
654 rowno->setBackColor(statusbar->getBackColor());
655
656 // Caption before number
657 new FXLabel(statusbar, _(" Line:"), NULL, LAYOUT_RIGHT|LAYOUT_CENTER_Y);
658
659 // Toolbar buttons: File manipulation
660 key = getApp()->reg().readStringEntry("KEYBINDINGS", "new", "Ctrl-N");
661 new FXButton(toolbar, TAB+_("New")+PARS(key)+TAB+_("Create new document.")+PARS(key), newfileicon, this, ID_NEW, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
662
663 key = getApp()->reg().readStringEntry("KEYBINDINGS", "open", "Ctrl-O");
664 new FXButton(toolbar, TAB+_("Open")+PARS(key)+TAB+_("Open document file.")+PARS(key), fileopenicon, this, ID_OPEN, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
665
666 key = getApp()->reg().readStringEntry("KEYBINDINGS", "save", "Ctrl-S");
667 new FXButton(toolbar, TAB+_("Save")+PARS(key)+TAB+_("Save document.")+PARS(key), savefileicon, this, ID_SAVE, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
668
669 key = getApp()->reg().readStringEntry("KEYBINDINGS", "close", "Ctrl-W");
670 new FXButton(toolbar, TAB+_("Close")+PARS(key)+TAB+_("Close document file.")+PARS(key), closefileicon, this, ID_CLOSE, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
671
672 // Spacer
673 new FXSeparator(toolbar, SEPARATOR_GROOVE);
674
675 // Toolbar buttons: Print and Quit
676 key = getApp()->reg().readStringEntry("KEYBINDINGS", "print", "Ctrl-P");
677 new FXButton(toolbar, TAB+_("Print")+PARS(key)+TAB+_("Print document.")+PARS(key), printicon, this, ID_PRINT, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
678
679 key = getApp()->reg().readStringEntry("KEYBINDINGS", "quit", "Ctrl-Q");
680 new FXButton(toolbar, TAB+_("Quit")+PARS(key)+TAB+_("Quit X File Write.")+PARS(key), quiticon, getApp(), XFileWrite::ID_CLOSEALL, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
681
682 // Spacer
683 new FXSeparator(toolbar, SEPARATOR_GROOVE);
684
685 // Toolbar buttons: Editing
686 key = getApp()->reg().readStringEntry("KEYBINDINGS", "copy", "Ctrl-C");
687 new FXButton(toolbar, TAB+_("Copy")+PARS(key)+TAB+_("Copy selection to clipboard.")+PARS(key), copy_clpicon, editor, FXText::ID_COPY_SEL, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
688
689 key = getApp()->reg().readStringEntry("KEYBINDINGS", "cut", "Ctrl-X");
690 cut = new FXButton(toolbar, TAB+_("Cut")+PARS(key)+TAB+_("Cut selection to clipboard.")+PARS(key), cut_clpicon, editor, FXText::ID_CUT_SEL, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
691
692 key = getApp()->reg().readStringEntry("KEYBINDINGS", "paste", "Ctrl-V");
693 paste = new FXButton(toolbar, TAB+_("Paste")+PARS(key)+TAB+_("Paste clipboard.")+PARS(key), paste_clpicon, editor, FXText::ID_PASTE_SEL, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
694
695 // Spacer
696 new FXSeparator(toolbar, SEPARATOR_GROOVE);
697
698 // Goto line
699 key = getApp()->reg().readStringEntry("KEYBINDINGS", "goto_line", "Ctrl-L");
700 new FXButton(toolbar, TAB+_("Goto line")+PARS(key)+TAB+_("Goto line number."), gotolineicon, this, WriteWindow::ID_GOTO_LINE, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
701
702 // Spacer
703 new FXSeparator(toolbar, SEPARATOR_GROOVE);
704
705 // Undo/redo
706 key = getApp()->reg().readStringEntry("KEYBINDINGS", "undo", "Ctrl-Z");
707 new FXButton(toolbar, TAB+_("Undo")+PARS(key)+TAB+_("Undo last change.")+PARS(key), undoicon, &undolist, FXUndoList::ID_UNDO, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
708
709 key = getApp()->reg().readStringEntry("KEYBINDINGS", "redo", "Ctrl-Y");
710 new FXButton(toolbar, TAB+_("Redo")+PARS(key)+TAB+_("Redo last undo.")+PARS(key), redoicon, &undolist, FXUndoList::ID_REDO, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
711
712 // Spacer
713 new FXSeparator(toolbar, SEPARATOR_GROOVE);
714
715 // Search
716 key = getApp()->reg().readStringEntry("KEYBINDINGS", "search", "Ctrl-F");
717 new FXButton(toolbar, TAB+_("Search")+PARS(key)+TAB+_("Search text.")+PARS(key), searchicon, this, WriteWindow::ID_SEARCH, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
718
719 key = getApp()->reg().readStringEntry("KEYBINDINGS", "search_prev", "Ctrl-Shift-G");
720 new FXButton(toolbar, TAB+_("Search selection backward")+PARS(key)+TAB+_("Search backward for selected text.")+PARS(key), searchprevicon, this, WriteWindow::ID_SEARCH_BACK_SEL, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
721
722 key = getApp()->reg().readStringEntry("KEYBINDINGS", "search_next", "Ctrl-G");
723 new FXButton(toolbar, TAB+_("Search selection forward")+PARS(key)+TAB+_("Search forward for selected text.")+PARS(key), searchnexticon, this, WriteWindow::ID_SEARCH_FORW_SEL, ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
724
725 // Spacer
726 new FXSeparator(toolbar, SEPARATOR_GROOVE);
727
728 // Preferences
729 key = getApp()->reg().readStringEntry("KEYBINDINGS", "word_wrap", "Ctrl-K");
730 new FXToggleButton(toolbar, TAB+_("Word wrap on")+PARS(key)+TAB+_("Set word wrap on.")+PARS(key), TAB+_("Word wrap off")+PARS(key)+TAB+_("Set word wrap off.")+PARS(key), wrapofficon, wraponicon, this, ID_TOGGLE_WRAP, BUTTON_TOOLBAR|LAYOUT_LEFT|ICON_BEFORE_TEXT);
731
732 key = getApp()->reg().readStringEntry("KEYBINDINGS", "line_numbers", "Ctrl-T");
733 new FXToggleButton(toolbar, TAB+_("Show line numbers")+PARS(key)+TAB+_("Show line numbers.")+PARS(key), TAB+_("Hide line numbers")+PARS(key)+TAB+_("Hide line numbers.")+PARS(key), hidenumbersicon, shownumbersicon, this, ID_TOGGLE_LINES_NUM, BUTTON_TOOLBAR|LAYOUT_LEFT|ICON_BEFORE_TEXT);
734
735
736 // File Menu entries
737 FXMenuCommand* mc = NULL;
738 FXString text;
739
740 key = getApp()->reg().readStringEntry("KEYBINDINGS", "new", "Ctrl-N");
741 text = _("&New")+TABS(key)+_("Create new document.")+PARS(key);
742 mc = new FXMenuCommand(filemenu, text, newfileicon, this, ID_NEW);
743 hotkey = _parseAccel(key);
744 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
745
746 key = getApp()->reg().readStringEntry("KEYBINDINGS", "open", "Ctrl-O");
747 text = _("&Open...")+TABS(key)+_("Open document file.")+PARS(key);
748 mc = new FXMenuCommand(filemenu, text, fileopenicon, this, ID_OPEN);
749 hotkey = _parseAccel(key);
750 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
751
752 key = getApp()->reg().readStringEntry("KEYBINDINGS", "save", "Ctrl-S");
753 text = _("&Save")+TABS(key)+_("Save changes to file.")+PARS(key);
754 mc = new FXMenuCommand(filemenu, text, savefileicon, this, ID_SAVE);
755 hotkey = _parseAccel(key);
756 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
757
758 new FXMenuCommand(filemenu, _("Save &As...")+TAB2+_("Save document to another file."), saveasicon, this, ID_SAVEAS);
759
760 key = getApp()->reg().readStringEntry("KEYBINDINGS", "close", "Ctrl-W");
761 text = _("&Close")+TABS(key)+_("Close document.")+PARS(key);
762 mc = new FXMenuCommand(filemenu, text, closefileicon, this, ID_CLOSE);
763 hotkey = _parseAccel(key);
764 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
765
766 new FXMenuSeparator(filemenu);
767 key = getApp()->reg().readStringEntry("KEYBINDINGS", "print", "Ctrl-P");
768 text = _("&Print...")+TABS(key)+_("Print document.")+PARS(key);
769 mc = new FXMenuCommand(filemenu, text, printicon, this, ID_PRINT);
770 hotkey = _parseAccel(key);
771 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
772
773 // Recent file menu; this automatically hides if there are no files
774 FXMenuSeparator* sep1 = new FXMenuSeparator(filemenu);
775 sep1->setTarget(&mrufiles);
776 sep1->setSelector(FXRecentFiles::ID_ANYFILES);
777 new FXMenuCommand(filemenu, FXString::null, NULL, &mrufiles, FXRecentFiles::ID_FILE_1);
778 new FXMenuCommand(filemenu, FXString::null, NULL, &mrufiles, FXRecentFiles::ID_FILE_2);
779 new FXMenuCommand(filemenu, FXString::null, NULL, &mrufiles, FXRecentFiles::ID_FILE_3);
780 new FXMenuCommand(filemenu, FXString::null, NULL, &mrufiles, FXRecentFiles::ID_FILE_4);
781 new FXMenuCommand(filemenu, FXString::null, NULL, &mrufiles, FXRecentFiles::ID_FILE_5);
782 new FXMenuCommand(filemenu, _("&Clear Recent Files"), NULL, &mrufiles, FXRecentFiles::ID_CLEAR);
783 FXMenuSeparator* sep2 = new FXMenuSeparator(filemenu);
784 sep2->setTarget(&mrufiles);
785 sep2->setSelector(FXRecentFiles::ID_ANYFILES);
786
787 key = getApp()->reg().readStringEntry("KEYBINDINGS", "quit", "Ctrl-Q");
788 text = _("&Quit")+TABS(key)+_("Quit X File Write.")+PARS(key);
789 mc = new FXMenuCommand(filemenu, text, quiticon, getApp(), XFileWrite::ID_CLOSEALL);
790 hotkey = _parseAccel(key);
791 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
792
793 // Edit Menu entries
794 key = getApp()->reg().readStringEntry("KEYBINDINGS", "undo", "Ctrl-Z");
795 text = _("&Undo")+TABS(key)+_("Undo last change.")+PARS(key);
796 mc = new FXMenuCommand(editmenu, text, undoicon, &undolist, FXUndoList::ID_UNDO);
797 hotkey = _parseAccel(key);
798 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
799
800 key = getApp()->reg().readStringEntry("KEYBINDINGS", "redo", "Ctrl-Y");
801 text = _("&Redo")+TABS(key)+_("Redo last undo.")+PARS(key);
802 mc = new FXMenuCommand(editmenu, text, redoicon, &undolist, FXUndoList::ID_REDO);
803 hotkey = _parseAccel(key);
804 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
805
806 new FXMenuCommand(editmenu, _("Revert to &saved")+TAB2+_("Revert to saved document."), reverticon, &undolist, FXUndoList::ID_REVERT);
807
808 new FXMenuSeparator(editmenu);
809 key = getApp()->reg().readStringEntry("KEYBINDINGS", "copy", "Ctrl-C");
810 text = _("&Copy")+TABS(key)+_("Copy selection to clipboard.")+PARS(key);
811 mc = new FXMenuCommand(editmenu, text, copy_clpicon, editor, FXText::ID_COPY_SEL);
812 hotkey = _parseAccel(key);
813 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
814
815 key = getApp()->reg().readStringEntry("KEYBINDINGS", "cut", "Ctrl-X");
816 text = _("Cu&t")+TABS(key)+_("Cut selection to clipboard.")+PARS(key);
817 cutmc = new FXMenuCommand(editmenu, text, cut_clpicon, editor, FXText::ID_CUT_SEL);
818 hotkey = _parseAccel(key);
819 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
820
821 key = getApp()->reg().readStringEntry("KEYBINDINGS", "paste", "Ctrl-V");
822 text = _("&Paste")+TABS(key)+_("Paste from clipboard.")+PARS(key);
823 pastemc = new FXMenuCommand(editmenu, text, paste_clpicon, editor, FXText::ID_PASTE_SEL);
824 hotkey = _parseAccel(key);
825 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
826
827 new FXMenuSeparator(editmenu);
828 key = getApp()->reg().readStringEntry("KEYBINDINGS", "lower_case", "Ctrl-U");
829 text = _("Lo&wer-case")+TABS(key)+_("Change to lower case.")+PARS(key);
830 mc = new FXMenuCommand(editmenu, text, lowercaseicon, editor, FXText::ID_LOWER_CASE);
831 hotkey = _parseAccel(key);
832 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
833
834 key = getApp()->reg().readStringEntry("KEYBINDINGS", "upper_case", "Ctrl-Shift-U");
835 text = _("Upp&er-case")+TABS(key)+_("Change to upper case.")+PARS(key);
836 mc = new FXMenuCommand(editmenu, text, uppercaseicon, editor, FXText::ID_UPPER_CASE);
837 hotkey = _parseAccel(key);
838 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
839
840 key = getApp()->reg().readStringEntry("KEYBINDINGS", "goto_line", "Ctrl-L");
841 text = _("&Goto line...")+TABS(key)+_("Goto line number.")+PARS(key);
842 mc = new FXMenuCommand(editmenu, text, gotolineicon, this, WriteWindow::ID_GOTO_LINE);
843 hotkey = _parseAccel(key);
844 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
845
846 // Right mouse popup
847 popupmenu = new FXMenuPane(this);
848 new FXMenuCommand(popupmenu, _("&Undo"), undoicon, &undolist, FXUndoList::ID_UNDO);
849 new FXMenuCommand(popupmenu, _("&Redo"), redoicon, &undolist, FXUndoList::ID_REDO);
850 new FXMenuSeparator(popupmenu);
851 new FXMenuCommand(popupmenu, _("&Copy"), copy_clpicon, editor, FXText::ID_COPY_SEL);
852 new FXMenuCommand(popupmenu, _("Cu&t"), cut_clpicon, editor, FXText::ID_CUT_SEL);
853 new FXMenuCommand(popupmenu, _("&Paste"), paste_clpicon, editor, FXText::ID_PASTE_SEL);
854 new FXMenuCommand(popupmenu, _("Select &All"), NULL, editor, FXText::ID_SELECT_ALL);
855 new FXMenuSeparator(popupmenu);
856
857 // View Menu entries
858 new FXMenuCheck(viewmenu, _("&Toolbar")+TAB2+_("Display toolbar."), toolbar, FXWindow::ID_TOGGLESHOWN);
859 new FXMenuCheck(viewmenu, _("&Status line")+TAB2+_("Display status line."), statusbar, FXWindow::ID_TOGGLESHOWN);
860
861 // Search Menu entries
862 key = getApp()->reg().readStringEntry("KEYBINDINGS", "search", "Ctrl-F");
863 text = _("&Search...")+TABS(key)+_("Search for a string.")+PARS(key);
864 mc = new FXMenuCommand(searchmenu, text, searchicon, this, WriteWindow::ID_SEARCH);
865 hotkey = _parseAccel(key);
866 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
867
868 key = getApp()->reg().readStringEntry("KEYBINDINGS", "replace", "Ctrl-R");
869 text = _("&Replace...")+TABS(key)+_("Search for a string and replace with another.")+PARS(key);
870 mc = new FXMenuCommand(searchmenu, text, replaceicon, this, WriteWindow::ID_REPLACE);
871 hotkey = _parseAccel(key);
872 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
873
874 key = getApp()->reg().readStringEntry("KEYBINDINGS", "search_prev", "Ctrl-Shift-G");
875 text = _("Search sel. &backward")+TABS(key)+_("Search backward for selected text.")+PARS(key);
876 mc = new FXMenuCommand(searchmenu, text, searchprevicon, this, WriteWindow::ID_SEARCH_BACK_SEL);
877 hotkey = _parseAccel(key);
878 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
879
880 key = getApp()->reg().readStringEntry("KEYBINDINGS", "search_next", "Ctrl-G");
881 text = _("Search sel. &forward")+TABS(key)+_("Search forward for selected text.")+PARS(key);
882 mc = new FXMenuCommand(searchmenu, text, searchnexticon, this, WriteWindow::ID_SEARCH_FORW_SEL);
883 hotkey = _parseAccel(key);
884 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
885
886
887 // Preferences menu
888 key = getApp()->reg().readStringEntry("KEYBINDINGS", "word_wrap", "Ctrl-K");
889 text = _("&Word wrap")+TABS(key)+_("Toggle word wrap mode.")+PARS(key);
890 mc = new FXMenuCheck(prefsmenu, text, this, ID_TOGGLE_WRAP);
891 hotkey = _parseAccel(key);
892 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
893
894 key = getApp()->reg().readStringEntry("KEYBINDINGS", "line_numbers", "Ctrl-T");
895 text = _("&Line numbers")+TABS(key)+_("Toggle line numbers mode.")+PARS(key);
896 mc = new FXMenuCheck(prefsmenu, text, this, ID_TOGGLE_LINES_NUM);
897 hotkey = _parseAccel(key);
898 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
899
900 new FXMenuCheck(prefsmenu, _("&Overstrike")+TAB2+_("Toggle overstrike mode."), editor, FXText::ID_TOGGLE_OVERSTRIKE);
901 new FXMenuSeparator(prefsmenu);
902 new FXMenuCommand(prefsmenu, _("&Font...")+TAB2+_("Change text font."), fontsicon, this, ID_FONT);
903 new FXMenuCommand(prefsmenu, _("&More preferences...")+TAB2+_("Change other options."), prefsicon, this, ID_PREFERENCES);
904
905 // Window menu
906 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_1);
907 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_2);
908 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_3);
909 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_4);
910 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_5);
911 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_6);
912 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_7);
913 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_8);
914 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_9);
915 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_10);
916 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_11);
917 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_12);
918 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_13);
919 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_14);
920 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_15);
921 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_16);
922 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_17);
923 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_18);
924 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_19);
925 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_20);
926 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_21);
927 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_22);
928 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_23);
929 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_24);
930 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_25);
931 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_26);
932 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_27);
933 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_28);
934 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_29);
935 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_30);
936 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_31);
937 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_32);
938 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_33);
939 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_34);
940 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_35);
941 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_36);
942 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_37);
943 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_38);
944 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_39);
945 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_40);
946 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_41);
947 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_42);
948 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_43);
949 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_44);
950 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_45);
951 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_46);
952 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_47);
953 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_48);
954 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_49);
955 new FXMenuRadio(windowmenu, FXString::null, this, ID_WINDOW_50);
956
957 // Help Menu entries
958 key = getApp()->reg().readStringEntry("KEYBINDINGS", "help", "F1");
959 text = _("&About X File Write")+TABS(key)+_("About X File Write.")+PARS(key);
960 mc = new FXMenuCommand(helpmenu, text, NULL, this, ID_ABOUT, 0);
961 hotkey = _parseAccel(key);
962 getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
963
964 // Dialogs
965 printdialog = NULL;
966 prefsdialog = NULL;
967 searchdialog = NULL;
968 replacedialog = NULL;
969
970 // Recent files
971 mrufiles.setTarget(this);
972 mrufiles.setSelector(ID_OPEN_RECENT);
973
974 // Initialize file name
975 filename = file;
976 filenameset = false;
977 filetime = 0;
978
979 // Initialize other stuff
980 stripcr = false;
981 linesnum = false;
982 undolist.mark();
983 undoredoblock = NULL;
984 smoothscroll = true;
985
986 // Initialize window position and size
987 fromreg = true;
988 ww = 0;
989 hh = 0;
990 xx = 0;
991 yy = 0;
992 }
993
994
995 // Create and show window
create()996 void WriteWindow::create()
997 {
998 loadConfig();
999 FXMainWindow::create();
1000 dragshell->create();
1001 filemenu->create();
1002 editmenu->create();
1003 searchmenu->create();
1004 prefsmenu->create();
1005 viewmenu->create();
1006 windowmenu->create();
1007 helpmenu->create();
1008 popupmenu->create();
1009 if (!urilistType)
1010 {
1011 urilistType = getApp()->registerDragType(urilistTypeName);
1012 }
1013 show(PLACEMENT_DEFAULT);
1014 editor->setFocus();
1015
1016 #ifdef STARTUP_NOTIFICATION
1017 startup_completed();
1018 #endif
1019 }
1020
1021
1022 // Detach window
detach()1023 void WriteWindow::detach()
1024 {
1025 FXMainWindow::detach();
1026 dragshell->detach();
1027 urilistType = 0;
1028 }
1029
1030
1031 // Clean up
~WriteWindow()1032 WriteWindow::~WriteWindow()
1033 {
1034 getApp()->windowlist.remove(this);
1035 delete font;
1036 delete toolbar;
1037 delete menubar;
1038 delete dragshell;
1039 delete filemenu;
1040 delete editmenu;
1041 delete searchmenu;
1042 delete prefsmenu;
1043 delete viewmenu;
1044 delete windowmenu;
1045 delete helpmenu;
1046 delete popupmenu;
1047 delete editor;
1048 delete printdialog;
1049 delete prefsdialog;
1050 delete searchdialog;
1051 delete replacedialog;
1052 }
1053
1054
1055 // Is it modified
isModified() const1056 FXbool WriteWindow::isModified() const
1057 {
1058 return(!undolist.marked());
1059 }
1060
1061
1062 // Load file
loadFile(const FXString & file)1063 FXbool WriteWindow::loadFile(const FXString& file)
1064 {
1065 FXFile textfile(file, FXFile::Reading);
1066 int size, n, i, j, c;
1067 char* text;
1068
1069 // Opened file?
1070 if (!textfile.isOpen())
1071 {
1072 MessageBox::error(this, BOX_OK, _("Error Loading File"), _("Unable to open file: %s"), file.text());
1073 return(false);
1074 }
1075
1076 // Get file size
1077 size = textfile.size();
1078
1079 // Make buffer to load file
1080 if (!FXMALLOC(&text, char, size))
1081 {
1082 MessageBox::error(this, BOX_OK, _("Error Loading File"), _("File is too big: %s (%d bytes)"), file.text(), size);
1083 return(false);
1084 }
1085
1086 // Set wait cursor
1087 getApp()->beginWaitCursor();
1088
1089 // Read the file
1090 n = textfile.readBlock(text, size);
1091 if (n < 0)
1092 {
1093 FXFREE(&text);
1094 MessageBox::error(this, BOX_OK, _("Error Loading File"), _("Unable to read file: %s"), file.text());
1095 getApp()->endWaitCursor();
1096 return(false);
1097 }
1098
1099 // Strip carriage returns
1100 if (stripcr)
1101 {
1102 for (i = j = 0; j < n; j++)
1103 {
1104 c = text[j];
1105 if (c != '\r')
1106 {
1107 text[i++] = c;
1108 }
1109 }
1110 n = i;
1111 }
1112
1113 // Set text
1114 editor->setText(text, n);
1115 FXFREE(&text);
1116
1117 // Lines numbering
1118 if (linesnum)
1119 {
1120 FXuint size = editor->getNumRows();
1121 FXuint cols = (FXuint)ceil(log10(size));
1122 editor->setBarColumns(cols);
1123 }
1124 else
1125 {
1126 editor->setBarColumns(0);
1127 }
1128
1129 // Kill wait cursor
1130 getApp()->endWaitCursor();
1131
1132 mrufiles.appendFile(file);
1133 filetime = FXStat::modified(file);
1134 filenameset = true;
1135 filename = file;
1136
1137 // Clear undo records
1138 undolist.clear();
1139
1140 // Mark undo state as clean (saved)
1141 undolist.mark();
1142
1143 return(true);
1144 }
1145
1146
1147 // Save file
saveFile(const FXString & file)1148 FXbool WriteWindow::saveFile(const FXString& file)
1149 {
1150 // Get current file size
1151 int size = editor->getLength();
1152
1153 // Get available space on current file system
1154 FXlong space = GetAvailableSpace(file);
1155
1156 // Unknown error
1157 if (space < 0)
1158 {
1159 MessageBox::error(this, BOX_OK, _("Error Saving File"), _("Unable to save file: %s"), file.text());
1160 return(false);
1161 }
1162
1163 // Not enough space left on file system to save the file
1164 else if (space < size)
1165 {
1166 MessageBox::error(this, BOX_OK, _("Error Saving File"), _("Not enough space left on device, unable to save file: %s\n\n\
1167 => To prevent losing data, you should save this file to another device before exiting!"), file.text());
1168 return(false);
1169 }
1170
1171 FXFile textfile(file, FXFile::Writing);
1172 char* text;
1173
1174 // Opened file?
1175 if (!textfile.isOpen())
1176 {
1177 MessageBox::error(this, BOX_OK, _("Error Saving File"), _("Unable to open file: %s"), file.text());
1178 return(false);
1179 }
1180
1181 // Alloc buffer
1182 if (!FXMALLOC(&text, char, size+1))
1183 {
1184 MessageBox::error(this, BOX_OK, _("Error Saving File"), _("File is too big: %s"), file.text());
1185 return(false);
1186 }
1187
1188 // Set wait cursor
1189 getApp()->beginWaitCursor();
1190
1191 // Get text from editor
1192 editor->getText(text, size);
1193
1194 // Write the file
1195 int n = textfile.writeBlock(text, size);
1196
1197 // Ditch buffer
1198 FXFREE(&text);
1199
1200 // Kill wait cursor
1201 getApp()->endWaitCursor();
1202
1203 // Were we able to write it all?
1204 if (n != size)
1205 {
1206 MessageBox::error(this, BOX_OK, _("Error Saving File"), _("File: %s truncated."), file.text());
1207 return(false);
1208 }
1209
1210 mrufiles.appendFile(file);
1211 filetime = FXStat::modified(file);
1212 filenameset = true;
1213 filename = file;
1214 undolist.mark();
1215 return(true);
1216 }
1217
1218
1219 // Generate unique name for a new window
unique() const1220 FXString WriteWindow::unique() const
1221 {
1222 FXString name = _("untitled");
1223
1224 for (int i = 1; i < 2147483647; i++)
1225 {
1226 if (!findWindow(name))
1227 {
1228 break;
1229 }
1230 name.format(_("untitled%d"), i);
1231 }
1232 return(name);
1233 }
1234
1235
1236 // Find an as yet untitled, unedited window
findUnused() const1237 WriteWindow* WriteWindow::findUnused() const
1238 {
1239 for (int w = 0; w < getApp()->windowlist.no(); w++)
1240 {
1241 if (!getApp()->windowlist[w]->isFilenameSet() && !getApp()->windowlist[w]->isModified())
1242 {
1243 return(getApp()->windowlist[w]);
1244 }
1245 }
1246 return(NULL);
1247 }
1248
1249
1250 // Find window, if any, currently editing the given file
findWindow(const FXString & file) const1251 WriteWindow* WriteWindow::findWindow(const FXString& file) const
1252 {
1253 for (int w = 0; w < getApp()->windowlist.no(); w++)
1254 {
1255 if (getApp()->windowlist[w]->getFilename() == file)
1256 {
1257 return(getApp()->windowlist[w]);
1258 }
1259 }
1260 return(NULL);
1261 }
1262
1263
1264 // Visit given line
visitLine(int line)1265 void WriteWindow::visitLine(int line)
1266 {
1267 int pos = editor->nextLine(0, line-1);
1268
1269 editor->setCursorPos(pos);
1270 editor->setCenterLine(pos);
1271 }
1272
1273
1274 // Read configuration from registry
loadConfig()1275 void WriteWindow::loadConfig()
1276 {
1277 FXColor textback, textfore, textselback, textselfore, textcursor, texthilitefore, texthiliteback;
1278 FXColor textbar, textnumber;
1279 int wrapping, wrapcols, tabcols;
1280 int hidestatus, hidetoolbar, hilitematchtime;
1281 FXString fontspec;
1282
1283 // Text colors
1284 textback = getApp()->reg().readColorEntry("OPTIONS", "textbackground", editor->getBackColor());
1285 textfore = getApp()->reg().readColorEntry("OPTIONS", "textforeground", editor->getTextColor());
1286 textselback = getApp()->reg().readColorEntry("OPTIONS", "textselbackground", editor->getSelBackColor());
1287 textselfore = getApp()->reg().readColorEntry("OPTIONS", "textselforeground", editor->getSelTextColor());
1288 textcursor = getApp()->reg().readColorEntry("OPTIONS", "textcursor", editor->getCursorColor());
1289 texthiliteback = getApp()->reg().readColorEntry("OPTIONS", "texthilitebackground", editor->getHiliteBackColor());
1290 texthilitefore = getApp()->reg().readColorEntry("OPTIONS", "texthiliteforeground", editor->getHiliteTextColor());
1291 textbar = getApp()->reg().readColorEntry("OPTIONS", "textnumberbackground", editor->getBarColor());
1292 textnumber = getApp()->reg().readColorEntry("OPTIONS", "textnumberforeground", editor->getNumberColor());
1293
1294 // Font
1295 fontspec = getApp()->reg().readStringEntry("OPTIONS", "textfont", "");
1296 if (!fontspec.empty())
1297 {
1298 font = new FXFont(getApp(), fontspec);
1299 font->create();
1300 editor->setFont(font);
1301 }
1302
1303 // Read the Xfe registry
1304 FXRegistry* reg_xfe = new FXRegistry(XFEAPPNAME, "");
1305 reg_xfe->read();
1306
1307 // Get value of the retain window position flag
1308 save_win_pos = reg_xfe->readUnsignedEntry("SETTINGS", "save_win_pos", false);
1309
1310 delete reg_xfe;
1311
1312 // Get size and position from registry
1313 if (fromreg)
1314 {
1315 ww = getApp()->reg().readUnsignedEntry("OPTIONS", "width", DEFAULT_WINDOW_WIDTH);
1316 hh = getApp()->reg().readUnsignedEntry("OPTIONS", "height", DEFAULT_WINDOW_HEIGHT);
1317 }
1318
1319 // Showing the status line?
1320 hidestatus = getApp()->reg().readIntEntry("OPTIONS", "hidestatus", false);
1321
1322 // Showing the tool bar?
1323 hidetoolbar = getApp()->reg().readIntEntry("OPTIONS", "hidetoolbar", false);
1324
1325 // Highlight match time
1326 hilitematchtime = getApp()->reg().readIntEntry("OPTIONS", "hilitematchtime", 3000);
1327
1328 // Word wrapping
1329 wrapping = getApp()->reg().readIntEntry("OPTIONS", "wordwrap", 0);
1330 wrapcols = getApp()->reg().readIntEntry("OPTIONS", "wrapcols", 80);
1331
1332 // Tab settings
1333 tabcols = getApp()->reg().readIntEntry("OPTIONS", "tabcols", 8);
1334
1335 // Various flags
1336 stripcr = getApp()->reg().readIntEntry("OPTIONS", "stripreturn", false);
1337 linesnum = getApp()->reg().readIntEntry("OPTIONS", "linesnum", false);
1338
1339 // Change the colors
1340 editor->setTextColor(textfore);
1341 editor->setBackColor(textback);
1342 editor->setSelBackColor(textselback);
1343 editor->setSelTextColor(textselfore);
1344 editor->setCursorColor(textcursor);
1345 editor->setHiliteBackColor(texthiliteback);
1346 editor->setHiliteTextColor(texthilitefore);
1347 editor->setBarColor(textbar);
1348 editor->setNumberColor(textnumber);
1349
1350
1351 // Hide statusline
1352 if (hidestatus)
1353 {
1354 statusbar->hide();
1355 }
1356
1357 // Hide toolbar
1358 if (hidetoolbar)
1359 {
1360 toolbar->hide();
1361 }
1362
1363 // Wrap mode
1364 if (wrapping)
1365 {
1366 editor->setTextStyle(editor->getTextStyle()|TEXT_WORDWRAP);
1367 }
1368 else
1369 {
1370 editor->setTextStyle(editor->getTextStyle()&~TEXT_WORDWRAP);
1371 }
1372
1373 // Wrap and tab columns
1374 editor->setWrapColumns(wrapcols);
1375 editor->setTabColumns(tabcols);
1376
1377 // Highlight match time
1378 editor->setHiliteMatchTime(hilitematchtime);
1379
1380 // Get position and position window
1381 if (save_win_pos && fromreg)
1382 {
1383 int xpos = getApp()->reg().readIntEntry("OPTIONS", "xpos", DEFAULT_WINDOW_XPOS);
1384 int ypos = getApp()->reg().readIntEntry("OPTIONS", "ypos", DEFAULT_WINDOW_YPOS);
1385 position(xpos, ypos, ww, hh);
1386 }
1387 else
1388 {
1389 position(getX(), getY(), ww, hh);
1390 }
1391 }
1392
1393
1394 // Save configuration to registry
saveConfig()1395 void WriteWindow::saveConfig()
1396 {
1397 FXString fontspec;
1398
1399 // Colors of text
1400 getApp()->reg().writeColorEntry("OPTIONS", "textbackground", editor->getBackColor());
1401 getApp()->reg().writeColorEntry("OPTIONS", "textforeground", editor->getTextColor());
1402 getApp()->reg().writeColorEntry("OPTIONS", "textselbackground", editor->getSelBackColor());
1403 getApp()->reg().writeColorEntry("OPTIONS", "textselforeground", editor->getSelTextColor());
1404 getApp()->reg().writeColorEntry("OPTIONS", "textcursor", editor->getCursorColor());
1405 getApp()->reg().writeColorEntry("OPTIONS", "texthilitebackground", editor->getHiliteBackColor());
1406 getApp()->reg().writeColorEntry("OPTIONS", "texthiliteforeground", editor->getHiliteTextColor());
1407 getApp()->reg().writeColorEntry("OPTIONS", "textnumberbackground", editor->getBarColor());
1408 getApp()->reg().writeColorEntry("OPTIONS", "textnumberforeground", editor->getNumberColor());
1409
1410
1411 // Write new window size back to registry
1412 getApp()->reg().writeUnsignedEntry("OPTIONS", "width", getWidth());
1413 getApp()->reg().writeUnsignedEntry("OPTIONS", "height", getHeight());
1414 if (save_win_pos)
1415 {
1416 // Account for the Window Manager border size
1417 XWindowAttributes xwattr;
1418 if (XGetWindowAttributes((Display*)getApp()->getDisplay(), this->id(), &xwattr))
1419 {
1420 getApp()->reg().writeIntEntry("OPTIONS", "xpos", getX()-xwattr.x);
1421 getApp()->reg().writeIntEntry("OPTIONS", "ypos", getY()-xwattr.y);
1422 }
1423 else
1424 {
1425 getApp()->reg().writeIntEntry("OPTIONS", "xpos", getX());
1426 getApp()->reg().writeIntEntry("OPTIONS", "ypos", getY());
1427 }
1428 }
1429
1430 // Was status line shown
1431 getApp()->reg().writeIntEntry("OPTIONS", "hidestatus", !statusbar->shown());
1432
1433 // Was toolbar shown
1434 getApp()->reg().writeIntEntry("OPTIONS", "hidetoolbar", !toolbar->shown());
1435
1436 // Highlight match time
1437 getApp()->reg().writeIntEntry("OPTIONS", "hilitematchtime", editor->getHiliteMatchTime());
1438
1439 // Wrap mode
1440 getApp()->reg().writeIntEntry("OPTIONS", "wordwrap", (editor->getTextStyle()&TEXT_WORDWRAP) != 0);
1441 getApp()->reg().writeIntEntry("OPTIONS", "wrapcols", editor->getWrapColumns());
1442
1443 // Tab settings
1444 getApp()->reg().writeIntEntry("OPTIONS", "tabcols", editor->getTabColumns());
1445
1446 // Strip returns
1447 getApp()->reg().writeIntEntry("OPTIONS", "stripreturn", stripcr);
1448 getApp()->reg().writeIntEntry("OPTIONS", "linesnum", linesnum);
1449
1450 // Search path
1451 getApp()->reg().writeStringEntry("OPTIONS", "searchpath", searchpath.text());
1452
1453 // Font
1454 fontspec = editor->getFont()->getFont();
1455 getApp()->reg().writeStringEntry("OPTIONS", "textfont", fontspec.text());
1456
1457 // Write registry options
1458 getApp()->reg().write();
1459 }
1460
1461
1462 // Harvest the zombies
onSigHarvest(FXObject *,FXSelector,void *)1463 long WriteWindow::onSigHarvest(FXObject*, FXSelector, void*)
1464 {
1465 while (waitpid(-1, NULL, WNOHANG) > 0)
1466 {
1467 }
1468 return(1);
1469 }
1470
1471
1472 // About box
onCmdAbout(FXObject *,FXSelector,void *)1473 long WriteWindow::onCmdAbout(FXObject*, FXSelector, void*)
1474 {
1475 FXString msg;
1476
1477 msg.format(_("X File Write Version %s is a simple text editor.\n\n"), VERSION);
1478 msg += COPYRIGHT;
1479 MessageBox about(this, _("About X File Write"), msg.text(), xfwicon, BOX_OK|DECOR_TITLE|DECOR_BORDER,
1480 JUSTIFY_CENTER_X|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y|LAYOUT_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
1481 about.execute(PLACEMENT_OWNER);
1482 return(1);
1483 }
1484
1485
1486 // Show preferences dialog
onCmdMorePrefs(FXObject *,FXSelector,void *)1487 long WriteWindow::onCmdMorePrefs(FXObject*, FXSelector, void*)
1488 {
1489 if (prefsdialog == NULL)
1490 {
1491 prefsdialog = new Preferences(this);
1492 }
1493 prefsdialog->execute(PLACEMENT_OWNER);
1494 return(1);
1495 }
1496
1497
1498 // Change text font
onCmdFont(FXObject *,FXSelector,void *)1499 long WriteWindow::onCmdFont(FXObject*, FXSelector, void*)
1500 {
1501 FontDialog fontdlg(this, _("Change Font"), DECOR_BORDER|DECOR_TITLE);
1502 FXFontDesc fontdesc;
1503
1504 editor->getFont()->getFontDesc(fontdesc);
1505 fontdlg.setFontSelection(fontdesc);
1506 if (fontdlg.execute())
1507 {
1508 FXFont* oldfont = font;
1509 fontdlg.getFontSelection(fontdesc);
1510 font = new FXFont(getApp(), fontdesc);
1511 font->create();
1512 editor->setFont(font);
1513 delete oldfont;
1514 }
1515 saveConfig();
1516 return(1);
1517 }
1518
1519
1520 // New
onCmdNew(FXObject *,FXSelector,void *)1521 long WriteWindow::onCmdNew(FXObject*, FXSelector, void*)
1522 {
1523 WriteWindow* window = new WriteWindow(getApp(), unique(), readonly);
1524
1525 // Smooth scrolling
1526 window->setSmoothScroll(smoothscroll);
1527
1528 window->create();
1529 window->raise();
1530 window->setFocus();
1531 return(1);
1532 }
1533
1534
1535 // Open
onCmdOpen(FXObject *,FXSelector,void *)1536 long WriteWindow::onCmdOpen(FXObject*, FXSelector, void*)
1537 {
1538 const char* patterns[] =
1539 {
1540 _("All Files"), "*",
1541 _("Text Files"), "*.txt",
1542 _("C Source Files"), "*.c",
1543 _("C++ Source Files"), "*.cpp",
1544 _("C++ Source Files"), "*.cc",
1545 _("C++ Source Files"), "*.cxx",
1546 _("C/C++ Header Files"), "*.h",
1547 _("HTML Files"), "*.html",
1548 _("HTML Files"), "*.htm",
1549 _("PHP Files"), "*.php", NULL
1550 };
1551
1552 FileDialog opendialog(this, _("Open Document"));
1553
1554 opendialog.setSelectMode(SELECTFILE_MULTIPLE);
1555 opendialog.setPatternList(patterns);
1556 opendialog.setDirectory(FXPath::directory(filename));
1557 if (opendialog.execute())
1558 {
1559 FXString* files = opendialog.getFilenames();
1560 FXuint i = 0;
1561 while (files[i] != FXString::null)
1562 {
1563 WriteWindow* window = findWindow(files[i]);
1564 if (!window)
1565 {
1566 window = findUnused();
1567 if (!window)
1568 {
1569 // New window
1570 window = new WriteWindow(getApp(), unique(), readonly);
1571
1572 // Smooth scrolling
1573 window->setSmoothScroll(smoothscroll);
1574
1575 // Set the size and position of the new window
1576 window->fromreg = false;
1577 window->ww = getWidth();
1578 window->hh = getHeight();
1579 window->xx = getX();
1580 window->yy = getY();
1581
1582 // Create window
1583 window->create();
1584 }
1585 window->loadFile(files[i]);
1586 }
1587 window->raise();
1588 window->setFocus();
1589 i++;
1590 }
1591 delete[] files;
1592 }
1593
1594 return(1);
1595 }
1596
1597
1598 // Open recent file
onCmdOpenRecent(FXObject *,FXSelector,void * ptr)1599 long WriteWindow::onCmdOpenRecent(FXObject*, FXSelector, void* ptr)
1600 {
1601 FXString file = (const char*)ptr;
1602 WriteWindow* window = findWindow(file);
1603
1604 if (!window)
1605 {
1606 window = findUnused();
1607 if (!window)
1608 {
1609 window = new WriteWindow(getApp(), unique(), readonly);
1610
1611 // Smooth scrolling
1612 window->setSmoothScroll(smoothscroll);
1613
1614 window->create();
1615 }
1616 window->loadFile(file);
1617 }
1618 window->raise();
1619 window->setFocus();
1620 return(1);
1621 }
1622
1623
1624 // See if we can get it as a filename
onEditDNDDrop(FXObject *,FXSelector,void *)1625 long WriteWindow::onEditDNDDrop(FXObject*, FXSelector, void*)
1626 {
1627 FXuchar* data;
1628 FXuint len;
1629
1630 if (getDNDData(FROM_DRAGNDROP, urilistType, data, len))
1631 {
1632 FXString urilist((FXchar*)data, len);
1633 FXString file = FXURL::fileFromURL(urilist.before('\r'));
1634 FXFREE(&data);
1635 if (file.empty())
1636 {
1637 return(1);
1638 }
1639 if (!saveChanges())
1640 {
1641 return(1);
1642 }
1643 loadFile(file);
1644 return(1);
1645 }
1646 return(0);
1647 }
1648
1649
1650 // See if a filename is being dragged over the window
onEditDNDMotion(FXObject *,FXSelector,void *)1651 long WriteWindow::onEditDNDMotion(FXObject*, FXSelector, void*)
1652 {
1653 if (offeredDNDType(FROM_DRAGNDROP, urilistType))
1654 {
1655 acceptDrop(DRAG_COPY);
1656 return(1);
1657 }
1658 return(0);
1659 }
1660
1661
1662 // Save changes, prompt for new filename
saveChanges()1663 FXbool WriteWindow::saveChanges()
1664 {
1665 FXuint answer;
1666 FXString file;
1667
1668 if (isModified())
1669 {
1670 answer = MessageBox::question(this, BOX_YES_NO_CANCEL, _("Unsaved Document"), _("Save %s to file?"), FXPath::name(filename).text());
1671 if (answer == BOX_CLICKED_CANCEL)
1672 {
1673 return(false);
1674 }
1675 if (answer == BOX_CLICKED_YES)
1676 {
1677 file = filename;
1678 if (!filenameset)
1679 {
1680 FileDialog savedialog(this, _("Save Document"));
1681 savedialog.setSelectMode(SELECTFILE_ANY);
1682 savedialog.setFilename(file);
1683 if (!savedialog.execute())
1684 {
1685 return(false);
1686 }
1687 file = savedialog.getFilename();
1688 if (existFile(file))
1689 {
1690 if (BOX_CLICKED_NO == MessageBox::question(this, BOX_YES_NO, _("Overwrite Document"), _("Overwrite existing document: %s?"), file.text()))
1691 {
1692 return(false);
1693 }
1694 }
1695 }
1696 saveFile(file);
1697 }
1698 }
1699 return(true);
1700 }
1701
1702
1703 // Save
onCmdSave(FXObject * sender,FXSelector sel,void * ptr)1704 long WriteWindow::onCmdSave(FXObject* sender, FXSelector sel, void* ptr)
1705 {
1706 if (!filenameset)
1707 {
1708 return(onCmdSaveAs(sender, sel, ptr));
1709 }
1710 saveFile(filename);
1711 return(1);
1712 }
1713
1714
1715 // Save Update
onUpdSave(FXObject * sender,FXSelector,void *)1716 long WriteWindow::onUpdSave(FXObject* sender, FXSelector, void*)
1717 {
1718 sender->handle(this, isModified() ? FXSEL(SEL_COMMAND, ID_ENABLE) : FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
1719 return(1);
1720 }
1721
1722
1723 // Disable menus and buttons when read only
onUpdReadOnly(FXObject * sender,FXSelector,void *)1724 long WriteWindow::onUpdReadOnly(FXObject* sender, FXSelector, void*)
1725 {
1726 sender->handle(this, readonly ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
1727
1728 // Disable cut and paste commands
1729 // (note: it seems that the context menu commands can't be disabled)
1730 //paste->disable();
1731 //pastemc->disable();
1732 //cut->disable();
1733 //cutmc->disable();
1734
1735 return(1);
1736 }
1737
1738
1739 // Save As
onCmdSaveAs(FXObject *,FXSelector,void *)1740 long WriteWindow::onCmdSaveAs(FXObject*, FXSelector, void*)
1741 {
1742 FileDialog savedialog(this, _("Save Document"));
1743 FXString file = filename;
1744
1745 savedialog.setSelectMode(SELECTFILE_ANY);
1746 savedialog.setFilename(file);
1747 if (savedialog.execute())
1748 {
1749 file = savedialog.getFilename();
1750 if (existFile(file))
1751 {
1752 if (BOX_CLICKED_NO == MessageBox::question(this, BOX_YES_NO, _("Overwrite Document"), _("Overwrite existing document: %s?"), file.text()))
1753 {
1754 return(1);
1755 }
1756 }
1757 saveFile(file);
1758 }
1759
1760 return(1);
1761 }
1762
1763
1764 // Close window
close(FXbool notify)1765 FXbool WriteWindow::close(FXbool notify)
1766 {
1767 // Prompt to save changes
1768 if (!saveChanges())
1769 {
1770 return(false);
1771 }
1772
1773 // Save settings
1774 saveConfig();
1775
1776 // Perform normal close stuff
1777 return(FXMainWindow::close(notify));
1778 }
1779
1780
1781 // User clicks on one of the window menus
onCmdWindow(FXObject *,FXSelector sel,void *)1782 long WriteWindow::onCmdWindow(FXObject*, FXSelector sel, void*)
1783 {
1784 int which = FXSELID(sel)-ID_WINDOW_1;
1785
1786 if (which < getApp()->windowlist.no())
1787 {
1788 getApp()->windowlist[which]->raise();
1789 getApp()->windowlist[which]->setFocus();
1790 }
1791 return(1);
1792 }
1793
1794
1795 // Update handler for window menus
onUpdWindow(FXObject * sender,FXSelector sel,void *)1796 long WriteWindow::onUpdWindow(FXObject* sender, FXSelector sel, void*)
1797 {
1798 int which = FXSELID(sel)-ID_WINDOW_1;
1799
1800 if (which < getApp()->windowlist.no())
1801 {
1802 WriteWindow* window = getApp()->windowlist[which];
1803 FXString string;
1804 if (which < 49)
1805 {
1806 string.format("&%d %s", which+1, window->getTitle().text());
1807 }
1808 else
1809 {
1810 string.format("5&0 %s", window->getTitle().text());
1811 }
1812
1813 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_SETSTRINGVALUE), (void*)&string);
1814
1815 if (window == getApp()->getActiveWindow())
1816 {
1817 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_CHECK), NULL);
1818 }
1819
1820 else
1821 {
1822 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_UNCHECK), NULL);
1823 }
1824 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_SHOW), NULL);
1825 }
1826 else
1827 {
1828 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_HIDE), NULL);
1829 }
1830 return(1);
1831 }
1832
1833
1834 // Update title from current filename
onUpdateTitle(FXObject * sender,FXSelector sel,void * ptr)1835 long WriteWindow::onUpdateTitle(FXObject* sender, FXSelector sel, void* ptr)
1836 {
1837 FXMainWindow::onUpdate(sender, sel, ptr);
1838 FXString title = FXPath::name(getFilename());
1839 if (isModified())
1840 {
1841 title += _(" (changed)");
1842 }
1843 FXString directory = FXPath::directory(getFilename());
1844 if (!directory.empty())
1845 {
1846 title += " - " + directory;
1847 }
1848
1849 if (readonly)
1850 {
1851 title += _(" (read only)");
1852 }
1853
1854 setTitle(title);
1855 return(1);
1856 }
1857
1858
1859 // Print the text
onCmdPrint(FXObject *,FXSelector,void *)1860 long WriteWindow::onCmdPrint(FXObject*, FXSelector, void*)
1861 {
1862 // Read the current print command from the registry
1863 FXString printcommand, command;
1864
1865 printcommand = getApp()->reg().readStringEntry("OPTIONS", "print_command", "lpr -P printer");
1866
1867 // Open print dialog filled with the current print command
1868 int rc = 1;
1869 if (printdialog == NULL)
1870 {
1871 printdialog = new InputDialog(this, printcommand, _("Print command: \n(ex: lpr -P <printer>)"), _("Print"), "", printbigicon);
1872 }
1873 printdialog->setText(printcommand);
1874 printdialog->CursorEnd();
1875 rc = printdialog->execute(PLACEMENT_CURSOR);
1876 printcommand = printdialog->getText();
1877
1878 // If cancel was pressed, exit
1879 if (!rc)
1880 {
1881 return(0);
1882 }
1883
1884 // Write the new print command to the registry
1885 getApp()->reg().writeStringEntry("OPTIONS", "print_command", printcommand.text());
1886
1887 // Perform the print command
1888 command = "cat " + filename + " |" + printcommand + " &";
1889 int ret = system(command.text());
1890 if (ret < 0)
1891 {
1892 MessageBox::error(this, BOX_OK, _("Error"), _("Can't execute command %s"), command.text());
1893 return(0);
1894 }
1895
1896 return(1);
1897 }
1898
1899
1900 // Toggle wrap mode
onCmdWrap(FXObject *,FXSelector,void *)1901 long WriteWindow::onCmdWrap(FXObject*, FXSelector, void*)
1902 {
1903 editor->setTextStyle(editor->getTextStyle()^TEXT_WORDWRAP);
1904 return(1);
1905 }
1906
1907
1908 // Update toggle wrap mode
onUpdWrap(FXObject * sender,FXSelector,void *)1909 long WriteWindow::onUpdWrap(FXObject* sender, FXSelector, void*)
1910 {
1911 if (editor->getTextStyle()&TEXT_WORDWRAP)
1912 {
1913 sender->handle(this, FXSEL(SEL_COMMAND, ID_CHECK), NULL);
1914 }
1915 else
1916 {
1917 sender->handle(this, FXSEL(SEL_COMMAND, ID_UNCHECK), NULL);
1918 }
1919 return(1);
1920 }
1921
1922
1923 // Toggle lines numbering
onCmdLinesNum(FXObject *,FXSelector,void *)1924 long WriteWindow::onCmdLinesNum(FXObject*, FXSelector, void*)
1925 {
1926 linesnum = !linesnum;
1927 if (linesnum)
1928 {
1929 FXuint size = editor->getNumRows();
1930 FXuint cols = (FXuint)ceil(log10(size));
1931 editor->setBarColumns(cols);
1932 }
1933 else
1934 {
1935 editor->setBarColumns(0);
1936 }
1937
1938 return(1);
1939 }
1940
1941
1942 // Update toggle line numbers
onUpdLinesNum(FXObject * sender,FXSelector,void *)1943 long WriteWindow::onUpdLinesNum(FXObject* sender, FXSelector, void*)
1944 {
1945 if (linesnum)
1946 {
1947 sender->handle(this, FXSEL(SEL_COMMAND, ID_CHECK), NULL);
1948 }
1949 else
1950 {
1951 sender->handle(this, FXSEL(SEL_COMMAND, ID_UNCHECK), NULL);
1952 }
1953 return(1);
1954 }
1955
1956
1957 // Update box for overstrike mode display
onUpdOverstrike(FXObject * sender,FXSelector,void *)1958 long WriteWindow::onUpdOverstrike(FXObject* sender, FXSelector, void*)
1959 {
1960 if (readonly)
1961 {
1962 FXString mode(_("READ ONLY"));
1963 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*)&mode);
1964 }
1965 else
1966 {
1967 FXString mode((editor->getTextStyle()&TEXT_OVERSTRIKE) ? _("OVR") : _("INS"));
1968 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*)&mode);
1969 }
1970
1971 return(1);
1972 }
1973
1974
1975 // Update box for size display
onUpdNumRows(FXObject * sender,FXSelector,void *)1976 long WriteWindow::onUpdNumRows(FXObject* sender, FXSelector, void*)
1977 {
1978 FXuint size = editor->getNumRows();
1979
1980 sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&size);
1981 return(1);
1982 }
1983
1984
1985 // Text inserted; callback has [pos nins]
onTextInserted(FXObject *,FXSelector,void * ptr)1986 long WriteWindow::onTextInserted(FXObject*, FXSelector, void* ptr)
1987 {
1988 const FXTextChange* change = (const FXTextChange*)ptr;
1989
1990 // Log undo record
1991 if (!undolist.busy())
1992 {
1993 undolist.add(new FXTextInsert(editor, change->pos, change->nins, change->ins));
1994 if (undolist.size() > MAXUNDOSIZE)
1995 {
1996 undolist.trimSize(KEEPUNDOSIZE);
1997 }
1998 }
1999
2000
2001 return(1);
2002 }
2003
2004
2005 // Text deleted; callback has [pos ndel]
onTextDeleted(FXObject *,FXSelector,void * ptr)2006 long WriteWindow::onTextDeleted(FXObject*, FXSelector, void* ptr)
2007 {
2008 const FXTextChange* change = (const FXTextChange*)ptr;
2009
2010 // Log undo record
2011 if (!undolist.busy())
2012 {
2013 undolist.add(new FXTextDelete(editor, change->pos, change->ndel, change->del));
2014 if (undolist.size() > MAXUNDOSIZE)
2015 {
2016 undolist.trimSize(KEEPUNDOSIZE);
2017 }
2018 }
2019
2020 return(1);
2021 }
2022
2023
2024 // Text replaced; callback has [pos ndel nins]
onTextReplaced(FXObject *,FXSelector,void * ptr)2025 long WriteWindow::onTextReplaced(FXObject*, FXSelector, void* ptr)
2026 {
2027 const FXTextChange* change = (const FXTextChange*)ptr;
2028
2029 // Log undo record
2030 if (!undolist.busy())
2031 {
2032 undolist.add(new FXTextReplace(editor, change->pos, change->ndel, change->nins, change->del, change->ins));
2033 if (undolist.size() > MAXUNDOSIZE)
2034 {
2035 undolist.trimSize(KEEPUNDOSIZE);
2036 }
2037 }
2038
2039 return(1);
2040 }
2041
2042
2043 // Released right button
onTextRightMouse(FXObject *,FXSelector,void * ptr)2044 long WriteWindow::onTextRightMouse(FXObject*, FXSelector, void* ptr)
2045 {
2046 FXEvent* event = (FXEvent*)ptr;
2047
2048 if (!event->moved)
2049 {
2050 allowPopupScroll = true; // Allow keyboard scrolling
2051 popupmenu->popup(NULL, event->root_x, event->root_y);
2052 getApp()->runModalWhileShown(popupmenu);
2053 allowPopupScroll = false;
2054 }
2055 return(1);
2056 }
2057
2058
2059 // Check file when focus moves in
onFocusIn(FXObject * sender,FXSelector sel,void * ptr)2060 long WriteWindow::onFocusIn(FXObject* sender, FXSelector sel, void* ptr)
2061 {
2062 register FXTime t;
2063
2064 FXMainWindow::onFocusIn(sender, sel, ptr);
2065 if (filetime != 0)
2066 {
2067 t = FXStat::modified(filename);
2068 if (t && (t != filetime))
2069 {
2070 filetime = t;
2071 if (BOX_CLICKED_OK == MessageBox::warning(this, BOX_OK_CANCEL, _("File Was Changed"), _("%s\nwas changed by another program. Reload this file from disk?"), filename.text()))
2072 {
2073 int top = editor->getTopLine();
2074 int pos = editor->getCursorPos();
2075 loadFile(filename);
2076 editor->setTopLine(top);
2077 editor->setCursorPos(pos);
2078 }
2079 }
2080 }
2081 return(1);
2082 }
2083
2084
2085 // Search text
onCmdSearch(FXObject *,FXSelector,void *)2086 long WriteWindow::onCmdSearch(FXObject*, FXSelector, void*)
2087 {
2088 if (searchdialog == NULL)
2089 {
2090 searchdialog = new FXSearchDialog(this, _("Search"), searchicon, options|DECOR_CLOSE);
2091 }
2092 searchdialog->setSearchMode(SEARCH_IGNORECASE);
2093
2094 int beg[10];
2095 int end[10];
2096 int pos;
2097 FXuint code;
2098 FXString searchstring;
2099 FXuint searchflags;
2100 do
2101 {
2102 code = searchdialog->execute();
2103 if (code == FXSearchDialog::DONE)
2104 {
2105 return(1);
2106 }
2107 searchstring = searchdialog->getSearchText();
2108 searchflags = searchdialog->getSearchMode();
2109 pos = editor->isPosSelected(editor->getCursorPos()) ? (searchflags&SEARCH_BACKWARD) ? editor->getSelStartPos()-1 : editor->getSelEndPos() : editor->getCursorPos();
2110 if (editor->findText(searchstring, beg, end, pos, searchflags|SEARCH_WRAP, 10))
2111 {
2112 editor->setAnchorPos(beg[0]);
2113 editor->extendSelection(end[0], SELECT_CHARS, true);
2114 editor->setCursorPos(end[0], true);
2115 editor->makePositionVisible(beg[0]);
2116 editor->makePositionVisible(end[0]);
2117 }
2118 else
2119 {
2120 getApp()->beep();
2121 }
2122 } while (code == FXSearchDialog::SEARCH_NEXT);
2123 return(1);
2124 }
2125
2126
2127 // Replace text; we assume that findText has called squeezegap()!
onCmdReplace(FXObject *,FXSelector,void *)2128 long WriteWindow::onCmdReplace(FXObject*, FXSelector, void*)
2129 {
2130 if (replacedialog == NULL)
2131 {
2132 replacedialog = new FXReplaceDialog(this, _("Replace"), replaceicon, options|DECOR_CLOSE);
2133 }
2134 replacedialog->setSearchMode(SEARCH_IGNORECASE);
2135
2136 int beg[10], end[10], fm, to, len, pos;
2137 FXuint searchflags, code;
2138 FXString searchstring;
2139 FXString replacestring;
2140 FXString replacevalue;
2141
2142 // Get text into buffer
2143 char* buffer;
2144 int length = editor->getLength();
2145 FXMALLOC(&buffer, char, length);
2146 editor->getText(buffer, length);
2147
2148 do
2149 {
2150 code = replacedialog->execute();
2151 if (code == FXReplaceDialog::DONE)
2152 {
2153 goto ret;
2154 }
2155 searchflags = replacedialog->getSearchMode();
2156 searchstring = replacedialog->getSearchText();
2157 replacestring = replacedialog->getReplaceText();
2158 replacevalue = FXString::null;
2159 fm = -1;
2160 to = -1;
2161 if (code == FXReplaceDialog::REPLACE_ALL)
2162 {
2163 searchflags &= ~SEARCH_BACKWARD;
2164 pos = 0;
2165 while (editor->findText(searchstring, beg, end, pos, searchflags, 10))
2166 {
2167 if (0 <= fm)
2168 {
2169 replacevalue.append(&buffer[pos], beg[0]-pos);
2170 }
2171 replacevalue.append(FXRex::substitute(buffer, length, beg, end, replacestring, 10));
2172 if (fm < 0)
2173 {
2174 fm = beg[0];
2175 }
2176 to = end[0];
2177 pos = end[0];
2178 if (beg[0] == end[0])
2179 {
2180 pos++;
2181 }
2182 }
2183 }
2184 else
2185 {
2186 pos = editor->isPosSelected(editor->getCursorPos()) ? (searchflags&SEARCH_BACKWARD) ? editor->getSelStartPos()-1 : editor->getSelEndPos() : editor->getCursorPos();
2187 if (editor->findText(searchstring, beg, end, pos, searchflags|SEARCH_WRAP, 10))
2188 {
2189 replacevalue = FXRex::substitute(buffer, length, beg, end, replacestring, 10);
2190 fm = beg[0];
2191 to = end[0];
2192 }
2193 }
2194 if (0 <= fm)
2195 {
2196 len = replacevalue.length();
2197 editor->replaceText(fm, to-fm, replacevalue.text(), len, true);
2198 editor->setCursorPos(fm+len, true);
2199 editor->makePositionVisible(editor->getCursorPos());
2200 editor->setModified(true);
2201 }
2202 else
2203 {
2204 getApp()->beep();
2205 }
2206 } while (code == FXReplaceDialog::REPLACE_NEXT);
2207
2208 ret:
2209 FXFREE(&buffer);
2210 return(1);
2211 }
2212
2213
2214 // Search for selected text
onCmdSearchSel(FXObject *,FXSelector sel,void *)2215 long WriteWindow::onCmdSearchSel(FXObject*, FXSelector sel, void*)
2216 {
2217 FXString string;
2218 FXuint searchflags;
2219 FXString searchstring;
2220 int pos = editor->getCursorPos();
2221 int beg, end;
2222
2223 // First, try UTF-8
2224 if (getDNDData(FROM_SELECTION, utf8Type, string))
2225 {
2226 searchstring = string;
2227 }
2228
2229 // Next, try UTF-16
2230 else if (getDNDData(FROM_SELECTION, utf16Type, string))
2231 {
2232 FXUTF16LECodec unicode; // FIXME maybe other endianness for unix
2233 searchstring = unicode.mb2utf(string);
2234 }
2235
2236 // Finally, try good old 8859-1
2237 else if (getDNDData(FROM_SELECTION, stringType, string))
2238 {
2239 FX88591Codec ascii;
2240 searchstring = ascii.mb2utf(string);
2241 }
2242
2243 // No dice!
2244 else
2245 {
2246 goto x;
2247 }
2248
2249 // Search direction
2250 if (FXSELID(sel) == ID_SEARCH_FORW_SEL)
2251 {
2252 if (editor->isPosSelected(pos))
2253 {
2254 pos = editor->getSelEndPos();
2255 }
2256 searchflags = SEARCH_EXACT|SEARCH_FORWARD;
2257 }
2258 else
2259 {
2260 if (editor->isPosSelected(pos))
2261 {
2262 pos = editor->getSelStartPos()-1;
2263 }
2264 searchflags = SEARCH_EXACT|SEARCH_BACKWARD;
2265 }
2266
2267 // Perform search
2268 if (editor->findText(searchstring, &beg, &end, pos, searchflags|SEARCH_WRAP))
2269 {
2270 if ((beg != editor->getSelStartPos()) || (end != editor->getSelEndPos()))
2271 {
2272 editor->setAnchorPos(beg);
2273 editor->extendSelection(end, SELECT_CHARS, true);
2274 editor->setCursorPos(end);
2275 editor->makePositionVisible(beg);
2276 editor->makePositionVisible(end);
2277 return(1);
2278 }
2279 }
2280
2281 // Beep
2282 x:
2283 getApp()->beep();
2284 return(1);
2285 }
2286
2287
2288 // Go to line number
onCmdGotoLine(FXObject *,FXSelector,void *)2289 long WriteWindow::onCmdGotoLine(FXObject*, FXSelector, void*)
2290 {
2291 int row = editor->getCursorRow()+1;
2292
2293 if (FXInputDialog::getInteger(row, this, _("Goto Line"), _("&Goto line number:"), gotobigicon, 1, 2147483647))
2294 {
2295 update();
2296 editor->setCursorRow(row-1, true);
2297 editor->makePositionVisible(editor->getCursorPos());
2298 }
2299 return(1);
2300 }
2301