1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2002 The LyX Team.
9 * ====================================================== */
15 #include "paragraph.h"
16 #include "BufferView.h"
17 #include "funcrequest.h"
20 #include "bufferparams.h"
22 #include "ParagraphParameters.h"
25 #include "support/lstrings.h"
26 #include "frontends/LyXView.h"
27 #include "frontends/WorkArea.h"
28 #include "insets/insetspecialchar.h"
29 #include "insets/insettext.h"
32 void LyXText::update(BufferView * bv, bool changed)
34 BufferView::UpdateCodes c = BufferView::SELECT | BufferView::FITCUR;
36 bv->update(this, c | BufferView::CHANGE);
42 void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind)
46 InsetSpecialChar * new_inset = new InsetSpecialChar(kind);
47 if (!bv->insertInset(new_inset))
50 bv->updateInset(new_inset, true);
54 Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
56 BufferView * bv = cmd.view();
61 Paragraph * par = cursor.par();
62 bool start = !par->params().startOfAppendix();
64 // ensure that we have only one start_of_appendix in this document
65 Paragraph * tmp = ownerParagraph();
66 for (; tmp; tmp = tmp->next())
67 tmp->params().startOfAppendix(false);
69 par->params().startOfAppendix(start);
71 // we can set the refreshing parameters now
72 status(cmd.view(), LyXText::NEED_MORE_REFRESH);
74 refresh_row = 0; // not needed for full update
75 updateCounters(cmd.view());
76 setCursor(cmd.view(), cursor.par(), cursor.pos());
78 return Inset::DISPATCHED;
81 case LFUN_DELETE_WORD_FORWARD:
82 bv->beforeChange(this);
84 deleteWordForward(bv);
87 return Inset::DISPATCHED;
89 case LFUN_DELETE_WORD_BACKWARD:
90 bv->beforeChange(this);
92 deleteWordBackward(bv);
95 return Inset::DISPATCHED;
97 case LFUN_DELETE_LINE_FORWARD:
98 bv->beforeChange(this);
100 deleteLineForward(bv);
103 return Inset::DISPATCHED;
107 if (!selection.mark())
108 bv->beforeChange(this);
112 return Inset::DISPATCHED;
115 if (!selection.mark())
116 bv->beforeChange(this);
118 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
119 cursorLeftOneWord(bv);
121 cursorRightOneWord(bv);
123 return Inset::DISPATCHED;
126 if (!selection.mark())
127 bv->beforeChange(this);
129 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
130 cursorRightOneWord(bv);
132 cursorLeftOneWord(bv);
134 return Inset::DISPATCHED;
136 case LFUN_BEGINNINGBUF:
137 if (!selection.mark())
138 bv->beforeChange(this);
142 return Inset::DISPATCHED;
145 if (selection.mark())
146 bv->beforeChange(this);
150 return Inset::DISPATCHED;
154 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
158 bv->finishChange(true);
159 return Inset::DISPATCHED;
163 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
167 bv->finishChange(true);
168 return Inset::DISPATCHED;
173 bv->finishChange(true);
174 return Inset::DISPATCHED;
178 cursorDown(bv, true);
179 bv->finishChange(true);
180 return Inset::DISPATCHED;
182 case LFUN_UP_PARAGRAPHSEL:
184 cursorUpParagraph(bv);
185 bv->finishChange(true);
186 return Inset::DISPATCHED;
188 case LFUN_DOWN_PARAGRAPHSEL:
190 cursorDownParagraph(bv);
191 bv->finishChange(true);
192 return Inset::DISPATCHED;
196 bv->cursorPrevious(this);
197 bv->finishChange(true);
198 return Inset::DISPATCHED;
202 bv->cursorNext(this);
204 return Inset::DISPATCHED;
209 bv->finishChange(true);
210 return Inset::DISPATCHED;
215 bv->finishChange(true);
216 return Inset::DISPATCHED;
218 case LFUN_WORDRIGHTSEL:
220 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
221 cursorLeftOneWord(bv);
223 cursorRightOneWord(bv);
224 bv->finishChange(true);
225 return Inset::DISPATCHED;
227 case LFUN_WORDLEFTSEL:
229 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
230 cursorRightOneWord(bv);
232 cursorLeftOneWord(bv);
233 bv->finishChange(true);
234 return Inset::DISPATCHED;
237 bool is_rtl = cursor.par()->isRightToLeftPar(bv->buffer()->params);
238 if (!selection.mark())
239 bv->beforeChange(this);
242 cursorLeft(bv, false);
243 if (cursor.pos() < cursor.par()->size()
244 && cursor.par()->isInset(cursor.pos())
245 && isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) {
246 Inset * tmpinset = cursor.par()->getInset(cursor.pos());
247 cmd.message(tmpinset->editMessage());
249 tmpinset->edit(bv, false);
252 return Inset::DISPATCHED;
255 cursorRight(bv, false);
256 bv->finishChange(false);
257 return Inset::DISPATCHED;
261 // This is soooo ugly. Isn`t it possible to make
263 bool const is_rtl = cursor.par()->isRightToLeftPar(bv->buffer()->params);
264 if (!selection.mark())
265 bv->beforeChange(this);
267 LyXCursor const cur = cursor;
269 cursorLeft(bv, false);
270 if ((is_rtl || cur != cursor) && // only if really moved!
271 cursor.pos() < cursor.par()->size() &&
272 cursor.par()->isInset(cursor.pos()) &&
273 isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) {
274 Inset * tmpinset = cursor.par()->getInset(cursor.pos());
275 cmd.message(tmpinset->editMessage());
279 tmpinset->edit(bv, false);
281 return Inset::DISPATCHED;
284 cursorRight(bv, false);
285 bv->finishChange(false);
286 return Inset::DISPATCHED;
290 if (!selection.mark())
291 bv->beforeChange(this);
292 bv->update(this, BufferView::UPDATE);
294 bv->finishChange(false);
295 return Inset::DISPATCHED;
298 if (!selection.mark())
299 bv->beforeChange(this);
300 bv->update(this, BufferView::UPDATE);
303 return Inset::DISPATCHED;
305 case LFUN_UP_PARAGRAPH:
306 if (!selection.mark())
307 bv->beforeChange(this);
308 bv->update(this, BufferView::UPDATE);
309 cursorUpParagraph(bv);
311 return Inset::DISPATCHED;
313 case LFUN_DOWN_PARAGRAPH:
314 if (!selection.mark())
315 bv->beforeChange(this);
316 bv->update(this, BufferView::UPDATE);
317 cursorDownParagraph(bv);
318 bv->finishChange(false);
319 return Inset::DISPATCHED;
322 if (!selection.mark())
323 bv->beforeChange(this);
324 bv->update(this, BufferView::UPDATE);
325 bv->cursorPrevious(this);
326 bv->finishChange(false);
329 // moveCursorUpdate(false, false);
330 // owner_->view_state_changed();
331 return Inset::DISPATCHED;
334 if (!selection.mark())
335 bv->beforeChange(this);
336 bv->update(this, BufferView::UPDATE);
337 bv->cursorNext(this);
338 bv->finishChange(false);
339 return Inset::DISPATCHED;
342 if (!selection.mark())
343 bv->beforeChange(this);
346 bv->finishChange(false);
347 return Inset::DISPATCHED;
350 if (!selection.mark())
351 bv->beforeChange(this);
354 bv->finishChange(false);
355 return Inset::DISPATCHED;
358 bv->beforeChange(this);
359 insertChar(bv, Paragraph::META_NEWLINE);
361 setCursor(bv, cursor.par(), cursor.pos());
362 bv->moveCursorUpdate(false);
363 return Inset::DISPATCHED;
365 case LFUN_PROTECTEDSPACE:
366 if (cursor.par()->layout()->free_spacing) {
370 specialChar(this, bv, InsetSpecialChar::PROTECTED_SEPARATOR);
372 bv->moveCursorUpdate(false);
373 return Inset::DISPATCHED;
375 case LFUN_HYPHENATION:
376 specialChar(this, bv, InsetSpecialChar::HYPHENATION);
377 return Inset::DISPATCHED;
379 case LFUN_LIGATURE_BREAK:
380 specialChar(this, bv, InsetSpecialChar::LIGATURE_BREAK);
381 return Inset::DISPATCHED;
384 specialChar(this, bv, InsetSpecialChar::LDOTS);
385 return Inset::DISPATCHED;
390 insertChar(bv, Paragraph::META_HFILL);
392 return Inset::DISPATCHED;
394 case LFUN_END_OF_SENTENCE:
395 specialChar(this, bv, InsetSpecialChar::END_OF_SENTENCE);
396 return Inset::DISPATCHED;
398 case LFUN_MENU_SEPARATOR:
399 specialChar(this, bv, InsetSpecialChar::MENU_SEPARATOR);
400 return Inset::DISPATCHED;
403 bv->beforeChange(this);
405 selection.cursor = cursor;
406 cmd.message(N_("Mark off"));
407 return Inset::DISPATCHED;
410 bv->beforeChange(this);
411 selection.mark(true);
413 selection.cursor = cursor;
414 cmd.message(N_("Mark on"));
415 return Inset::DISPATCHED;
418 bv->beforeChange(this);
419 if (selection.mark()) {
421 cmd.message(N_("Mark removed"));
423 selection.mark(true);
425 cmd.message(N_("Mark set"));
427 selection.cursor = cursor;
428 return Inset::DISPATCHED;
430 case LFUN_UPCASE_WORD:
432 changeCase(bv, LyXText::text_uppercase);
434 bv->updateInset(inset_owner, true);
436 return Inset::DISPATCHED;
438 case LFUN_LOWCASE_WORD:
440 changeCase(bv, LyXText::text_lowercase);
442 bv->updateInset(inset_owner, true);
444 return Inset::DISPATCHED;
446 case LFUN_CAPITALIZE_WORD:
448 changeCase(bv, LyXText::text_capitalization);
450 bv->updateInset(inset_owner, true);
452 return Inset::DISPATCHED;
454 case LFUN_TRANSPOSE_CHARS:
458 bv->updateInset(inset_owner, true);
460 return Inset::DISPATCHED;
462 case LFUN_BEGINNINGBUFSEL:
464 return Inset::UNDISPATCHED;
467 bv->finishChange(true);
468 return Inset::DISPATCHED;
472 return Inset::UNDISPATCHED;
475 bv->finishChange(true);
476 return Inset::DISPATCHED;
479 cmd.message(tostr(cursor.x()) + ' ' + tostr(cursor.y()));
480 return Inset::DISPATCHED;
485 if (::sscanf(cmd.argument.c_str(), " %d %d", &x, &y) != 2)
486 lyxerr << "SETXY: Could not parse coordinates in '"
487 << cmd.argument << std::endl;
488 setCursorFromCoordinates(bv, x, y);
489 return Inset::DISPATCHED;
493 if (current_font.shape() == LyXFont::ITALIC_SHAPE)
495 else if (current_font.shape() == LyXFont::SMALLCAPS_SHAPE)
499 return Inset::DISPATCHED;
502 cmd.message(tostr(cursor.par()->layout()));
503 return Inset::DISPATCHED;
505 case LFUN_SELFINSERT: {
506 if (cmd.argument.empty())
507 return Inset::DISPATCHED;
509 // Automatically delete the currently selected
510 // text and replace it with what is being
511 // typed in now. Depends on lyxrc settings
512 // "auto_region_delete", which defaults to
515 if (lyxrc.auto_region_delete) {
516 if (selection.set()) {
517 cutSelection(bv, false, false);
520 bv->workarea().haveSelection(false);
523 bv->beforeChange(this);
524 LyXFont const old_font(real_current_font);
526 string::const_iterator cit = cmd.argument.begin();
527 string::const_iterator end = cmd.argument.end();
528 for (; cit != end; ++cit)
529 bv->owner()->getIntl().getTransManager().
530 TranslateAndInsert(*cit, this);
533 selection.cursor = cursor;
534 bv->moveCursorUpdate(false);
536 // real_current_font.number can change so we need to
537 // update the minibuffer
538 if (old_font != real_current_font)
539 bv->owner()->view_state_changed();
540 return Inset::DISPATCHED;
544 return Inset::UNDISPATCHED;
548 return Inset::UNDISPATCHED;