]> git.lyx.org Git - lyx.git/blob - src/text3.C
compile fixes
[lyx.git] / src / text3.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2002 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #include "lyxtext.h"
14 #include "lyxrow.h"
15 #include "paragraph.h"
16 #include "BufferView.h"
17 #include "funcrequest.h"
18 #include "lyxrc.h"
19 #include "debug.h"
20 #include "bufferparams.h"
21 #include "buffer.h"
22 #include "ParagraphParameters.h"
23 #include "gettext.h"
24 #include "intl.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"
30
31 using std::endl;
32
33 extern string current_layout;
34
35
36 void LyXText::update(BufferView * bv, bool changed)
37 {
38         BufferView::UpdateCodes c = BufferView::SELECT | BufferView::FITCUR;
39         if (changed)
40                 bv->update(this, c | BufferView::CHANGE);
41         else
42                 bv->update(this, c);
43 }
44
45
46 void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind)
47 {
48         bv->hideCursor();
49         lt->update(bv);
50         InsetSpecialChar * new_inset = new InsetSpecialChar(kind);
51         if (!bv->insertInset(new_inset))
52                 delete new_inset;
53         else
54                 bv->updateInset(new_inset, true);
55 }
56
57
58 Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
59 {
60         BufferView * bv = cmd.view();
61
62         switch (cmd.action) {
63
64         case LFUN_APPENDIX: {
65                 Paragraph * par = cursor.par();
66                 bool start = !par->params().startOfAppendix();
67
68                 // ensure that we have only one start_of_appendix in this document
69                 Paragraph * tmp = ownerParagraph();
70                 for (; tmp; tmp = tmp->next())
71                         tmp->params().startOfAppendix(false);
72
73                 par->params().startOfAppendix(start);
74
75                 // we can set the refreshing parameters now
76                 status(cmd.view(), LyXText::NEED_MORE_REFRESH);
77                 refresh_y = 0;
78                 refresh_row = 0; // not needed for full update
79                 updateCounters(cmd.view());
80                 setCursor(cmd.view(), cursor.par(), cursor.pos());
81                 update(bv);
82                 break;
83         }
84
85         case LFUN_DELETE_WORD_FORWARD:
86                 bv->beforeChange(this);
87                 update(bv, false);
88                 deleteWordForward(bv);
89                 update(bv);
90                 bv->finishChange();
91                 break;
92
93         case LFUN_DELETE_WORD_BACKWARD:
94                 bv->beforeChange(this);
95                 update(bv, false);
96                 deleteWordBackward(bv);
97                 update(bv, true);
98                 bv->finishChange();
99                 break;
100
101         case LFUN_DELETE_LINE_FORWARD:
102                 bv->beforeChange(this);
103                 update(bv, false);
104                 deleteLineForward(bv);
105                 update(bv);
106                 bv->finishChange();
107                 break;
108
109         case LFUN_SHIFT_TAB:
110         case LFUN_TAB:
111                 if (!selection.mark())
112                         bv->beforeChange(this);
113                 update(bv, false);
114                 cursorTab(bv);
115                 bv->finishChange();
116                 break;
117
118         case LFUN_WORDRIGHT:
119                 if (!selection.mark())
120                         bv->beforeChange(this);
121                 update(bv, false);
122                 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
123                         cursorLeftOneWord(bv);
124                 else
125                         cursorRightOneWord(bv);
126                 bv->finishChange();
127                 break;
128
129         case LFUN_WORDLEFT:
130                 if (!selection.mark())
131                         bv->beforeChange(this);
132                 update(bv, false);
133                 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
134                         cursorRightOneWord(bv);
135                 else
136                         cursorLeftOneWord(bv);
137                 bv->finishChange();
138                 break;
139
140         case LFUN_BEGINNINGBUF:
141                 if (!selection.mark())
142                         bv->beforeChange(this);
143                 update(bv, false);
144                 cursorTop(bv);
145                 bv->finishChange();
146                 break;
147
148         case LFUN_ENDBUF:
149                 if (selection.mark())
150                         bv->beforeChange(this);
151                 update(bv, false);
152                 cursorBottom(bv);
153                 bv->finishChange();
154                 break;
155
156         case LFUN_RIGHTSEL:
157                 update(bv, false);
158                 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
159                         cursorLeft(bv);
160                 else
161                         cursorRight(bv);
162                 bv->finishChange(true);
163                 break;
164
165         case LFUN_LEFTSEL:
166                 update(bv, false);
167                 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
168                         cursorRight(bv);
169                 else
170                         cursorLeft(bv);
171                 bv->finishChange(true);
172                 break;
173
174         case LFUN_UPSEL:
175                 update(bv, false);
176                 cursorUp(bv, true);
177                 bv->finishChange(true);
178                 break;
179
180         case LFUN_DOWNSEL:
181                 update(bv, false);
182                 cursorDown(bv, true);
183                 bv->finishChange(true);
184                 break;
185
186         case LFUN_UP_PARAGRAPHSEL:
187                 update(bv, false);
188                 cursorUpParagraph(bv);
189                 bv->finishChange(true);
190                 break;
191
192         case LFUN_DOWN_PARAGRAPHSEL:
193                 update(bv, false);
194                 cursorDownParagraph(bv);
195                 bv->finishChange(true);
196                 break;
197
198         case LFUN_PRIORSEL:
199                 update(bv, false);
200                 bv->cursorPrevious(this);
201                 bv->finishChange(true);
202                 break;
203
204         case LFUN_NEXTSEL:
205                 update(bv, false);
206                 bv->cursorNext(this);
207                 bv->finishChange();
208                 break;
209
210         case LFUN_HOMESEL:
211                 update(bv, false);
212                 cursorHome(bv);
213                 bv->finishChange(true);
214                 break;
215
216         case LFUN_ENDSEL:
217                 update(bv, false);
218                 cursorEnd(bv);
219                 bv->finishChange(true);
220                 break;
221
222         case LFUN_WORDRIGHTSEL:
223                 update(bv, false);
224                 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
225                         cursorLeftOneWord(bv);
226                 else
227                         cursorRightOneWord(bv);
228                 bv->finishChange(true);
229                 break;
230
231         case LFUN_WORDLEFTSEL:
232                 update(bv, false);
233                 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
234                         cursorRightOneWord(bv);
235                 else
236                         cursorLeftOneWord(bv);
237                 bv->finishChange(true);
238                 break;
239
240         case LFUN_RIGHT: {
241                 bool is_rtl = cursor.par()->isRightToLeftPar(bv->buffer()->params);
242                 if (!selection.mark())
243                         bv->beforeChange(this);
244                 update(bv);
245                 if (is_rtl)
246                         cursorLeft(bv, false);
247                 if (cursor.pos() < cursor.par()->size()
248                     && cursor.par()->isInset(cursor.pos())
249                     && isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) {
250                         Inset * tmpinset = cursor.par()->getInset(cursor.pos());
251                         cmd.message(tmpinset->editMessage());
252                         tmpinset->edit(bv, !is_rtl);
253                         break;
254                 }
255                 if (!is_rtl)
256                         cursorRight(bv, false);
257                 bv->finishChange(false);
258                 break;
259         }
260
261         case LFUN_LEFT: {
262                 // This is soooo ugly. Isn`t it possible to make
263                 // it simpler? (Lgb)
264                 bool const is_rtl = cursor.par()->isRightToLeftPar(bv->buffer()->params);
265                 if (!selection.mark())
266                         bv->beforeChange(this);
267                 update(bv);
268                 LyXCursor const cur = cursor;
269                 if (!is_rtl)
270                         cursorLeft(bv, false);
271                 if ((is_rtl || cur != cursor) && // only if really moved!
272                     cursor.pos() < cursor.par()->size() &&
273                     cursor.par()->isInset(cursor.pos()) &&
274                     isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) {
275                         Inset * tmpinset = cursor.par()->getInset(cursor.pos());
276                         cmd.message(tmpinset->editMessage());
277                         tmpinset->edit(bv, is_rtl);
278                         break;
279                 }
280                 if (is_rtl)
281                         cursorRight(bv, false);
282                 bv->finishChange(false);
283                 break;
284         }
285
286         case LFUN_UP:
287                 if (!selection.mark())
288                         bv->beforeChange(this);
289                 bv->update(this, BufferView::UPDATE);
290                 cursorUp(bv);
291                 bv->finishChange(false);
292                 break;
293
294         case LFUN_DOWN:
295                 if (!selection.mark())
296                         bv->beforeChange(this);
297                 bv->update(this, BufferView::UPDATE);
298                 cursorDown(bv);
299                 bv->finishChange();
300                 break;
301
302         case LFUN_UP_PARAGRAPH:
303                 if (!selection.mark())
304                         bv->beforeChange(this);
305                 bv->update(this, BufferView::UPDATE);
306                 cursorUpParagraph(bv);
307                 bv->finishChange();
308                 break;
309
310         case LFUN_DOWN_PARAGRAPH:
311                 if (!selection.mark())
312                         bv->beforeChange(this);
313                 bv->update(this, BufferView::UPDATE);
314                 cursorDownParagraph(bv);
315                 bv->finishChange(false);
316                 break;
317
318         case LFUN_PRIOR:
319                 if (!selection.mark())
320                         bv->beforeChange(this);
321                 bv->update(this, BufferView::UPDATE);
322                 bv->cursorPrevious(this);
323                 bv->finishChange(false);
324                 // was:
325                 // finishUndo();
326                 // moveCursorUpdate(false, false);
327                 // owner_->view_state_changed();
328                 break;
329
330         case LFUN_NEXT:
331                 if (!selection.mark())
332                         bv->beforeChange(this);
333                 bv->update(this, BufferView::UPDATE);
334                 bv->cursorNext(this);
335                 bv->finishChange(false);
336                 break;
337
338         case LFUN_HOME:
339                 if (!selection.mark())
340                         bv->beforeChange(this);
341                 update(bv);
342                 cursorHome(bv);
343                 bv->finishChange(false);
344                 break;
345
346         case LFUN_END:
347                 if (!selection.mark())
348                         bv->beforeChange(this);
349                 update(bv);
350                 cursorEnd(bv);
351                 bv->finishChange(false);
352                 break;
353
354         case LFUN_BREAKLINE:
355                 bv->beforeChange(this);
356                 insertChar(bv, Paragraph::META_NEWLINE);
357                 update(bv, true);
358                 setCursor(bv, cursor.par(), cursor.pos());
359                 bv->moveCursorUpdate(false);
360                 break;
361
362         case LFUN_DELETE:
363                 if (!selection.set()) {
364                         Delete(bv);
365                         selection.cursor = cursor;
366                         update(bv);
367                         // It is possible to make it a lot faster still
368                         // just comment out the line below...
369                         bv->showCursor();
370                 } else {
371                         bv->cut(false);
372                 }
373                 bv->moveCursorUpdate(false);
374                 bv->owner()->view_state_changed();
375                 bv->switchKeyMap();
376                 break;
377
378         case LFUN_DELETE_SKIP:
379                 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
380                 if (!selection.set()) {
381                         LyXCursor cur = cursor;
382                         if (cur.pos() == cur.par()->size()) {
383                                 cursorRight(bv);
384                                 cur = cursor;
385                                 if (cur.pos() == 0
386                                     && !(cur.par()->params().spaceTop()
387                                          == VSpace (VSpace::NONE))) {
388                                         setParagraph(bv,
389                                                  cur.par()->params().lineTop(),
390                                                  cur.par()->params().lineBottom(),
391                                                  cur.par()->params().pagebreakTop(),
392                                                  cur.par()->params().pagebreakBottom(),
393                                                  VSpace(VSpace::NONE),
394                                                  cur.par()->params().spaceBottom(),
395                                                  cur.par()->params().spacing(),
396                                                  cur.par()->params().align(),
397                                                  cur.par()->params().labelWidthString(), 0);
398                                         cursorLeft(bv);
399                                         update(bv);
400                                 } else {
401                                         cursorLeft(bv);
402                                         Delete(bv);
403                                         selection.cursor = cursor;
404                                         update(bv);
405                                 }
406                         } else {
407                                 Delete(bv);
408                                 selection.cursor = cursor;
409                                 update(bv);
410                         }
411                 } else
412                         bv->cut(false);
413                 break;
414
415
416         case LFUN_BACKSPACE:
417                 if (!selection.set()) {
418                         if (bv->owner()->getIntl().getTransManager().backspace()) {
419                                 backspace(bv);
420                                 selection.cursor = cursor;
421                                 update(bv);
422                                 // It is possible to make it a lot faster still
423                                 // just comment out the line below...
424                                 bv->showCursor();
425                         }
426                 } else
427                         bv->cut(false);
428                 bv->owner()->view_state_changed();
429                 bv->switchKeyMap();
430                 break;
431
432         case LFUN_BACKSPACE_SKIP:
433                 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
434                 if (!selection.set()) {
435                         LyXCursor cur = cursor;
436                         if (cur.pos() == 0
437                             && !(cur.par()->params().spaceTop()
438                                  == VSpace (VSpace::NONE))) {
439                                 setParagraph(bv,
440                                          cur.par()->params().lineTop(),
441                                          cur.par()->params().lineBottom(),
442                                          cur.par()->params().pagebreakTop(),
443                                          cur.par()->params().pagebreakBottom(),
444                                          VSpace(VSpace::NONE), cur.par()->params().spaceBottom(),
445                                          cur.par()->params().spacing(),
446                                          cur.par()->params().align(),
447                                          cur.par()->params().labelWidthString(), 0);
448                                 update(bv);
449                         } else {
450                                 backspace(bv);
451                                 selection.cursor = cur;
452                                 update(bv);
453                         }
454                 } else
455                         bv->cut(false);
456                 break;
457
458         case LFUN_BREAKPARAGRAPH:
459                 bv->beforeChange(this);
460                 breakParagraph(bv, 0);
461                 update(bv);
462                 selection.cursor = cursor;
463                 bv->switchKeyMap();
464                 bv->owner()->view_state_changed();
465                 break;
466
467         case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
468                 bv->beforeChange(this);
469                 breakParagraph(bv, 1);
470                 update(bv);
471                 selection.cursor = cursor;
472                 bv->switchKeyMap();
473                 bv->owner()->view_state_changed();
474                 break;
475
476         case LFUN_BREAKPARAGRAPH_SKIP: {
477                 // When at the beginning of a paragraph, remove
478                 // indentation and add a "defskip" at the top.
479                 // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
480                 LyXCursor cur = cursor;
481                 bv->beforeChange(this);
482                 if (cur.pos() == 0) {
483                         if (cur.par()->params().spaceTop() == VSpace(VSpace::NONE)) {
484                                 setParagraph(bv,
485                                          cur.par()->params().lineTop(),
486                                          cur.par()->params().lineBottom(),
487                                          cur.par()->params().pagebreakTop(),
488                                          cur.par()->params().pagebreakBottom(),
489                                          VSpace(VSpace::DEFSKIP), cur.par()->params().spaceBottom(),
490                                          cur.par()->params().spacing(),
491                                          cur.par()->params().align(),
492                                          cur.par()->params().labelWidthString(), 1);
493                                 //update(bv);
494                         }
495                 }
496                 else {
497                         breakParagraph(bv, 0);
498                         //update(bv);
499                 }
500                 update(bv);
501                 selection.cursor = cur;
502                 bv->switchKeyMap();
503                 bv->owner()->view_state_changed();
504                 break;
505         }
506
507         case LFUN_PARAGRAPH_SPACING: {
508                 Paragraph * par = cursor.par();
509                 Spacing::Space cur_spacing = par->params().spacing().getSpace();
510                 float cur_value = 1.0;
511                 if (cur_spacing == Spacing::Other)
512                         cur_value = par->params().spacing().getValue();
513
514                 istringstream is(cmd.argument.c_str());
515                 string tmp;
516                 is >> tmp;
517                 Spacing::Space new_spacing = cur_spacing;
518                 float new_value = cur_value;
519                 if (tmp.empty()) {
520                         lyxerr << "Missing argument to `paragraph-spacing'"
521                                << endl;
522                 } else if (tmp == "single") {
523                         new_spacing = Spacing::Single;
524                 } else if (tmp == "onehalf") {
525                         new_spacing = Spacing::Onehalf;
526                 } else if (tmp == "double") {
527                         new_spacing = Spacing::Double;
528                 } else if (tmp == "other") {
529                         new_spacing = Spacing::Other;
530                         float tmpval = 0.0;
531                         is >> tmpval;
532                         lyxerr << "new_value = " << tmpval << endl;
533                         if (tmpval != 0.0)
534                                 new_value = tmpval;
535                 } else if (tmp == "default") {
536                         new_spacing = Spacing::Default;
537                 } else {
538                         lyxerr << _("Unknown spacing argument: ")
539                                << cmd.argument << endl;
540                 }
541                 if (cur_spacing != new_spacing || cur_value != new_value) {
542                         par->params().spacing(Spacing(new_spacing, new_value));
543                         redoParagraph(bv);
544                         update(bv);
545                 }
546                 break;
547         }
548
549         case LFUN_INSET_TOGGLE:
550                 bv->hideCursor();
551                 bv->beforeChange(this);
552                 update(bv, false);
553                 toggleInset(bv);
554                 update(bv, false);
555                 bv->switchKeyMap();
556                 break;
557
558         case LFUN_PROTECTEDSPACE:
559                 if (cursor.par()->layout()->free_spacing) {
560                         insertChar(bv, ' ');
561                         update(bv);
562                 } else {
563                         specialChar(this, bv, InsetSpecialChar::PROTECTED_SEPARATOR);
564                 }
565                 bv->moveCursorUpdate(false);
566                 break;
567
568         case LFUN_HYPHENATION:
569                 specialChar(this, bv, InsetSpecialChar::HYPHENATION);
570                 break;
571
572         case LFUN_LIGATURE_BREAK:
573                 specialChar(this, bv, InsetSpecialChar::LIGATURE_BREAK);
574                 break;
575
576         case LFUN_LDOTS:
577                 specialChar(this, bv, InsetSpecialChar::LDOTS);
578                 break;
579
580         case LFUN_HFILL:
581                 bv->hideCursor();
582                 update(bv, false);
583                 insertChar(bv, Paragraph::META_HFILL);
584                 update(bv);
585                 break;
586
587         case LFUN_END_OF_SENTENCE:
588                 specialChar(this, bv, InsetSpecialChar::END_OF_SENTENCE);
589                 break;
590
591         case LFUN_MENU_SEPARATOR:
592                 specialChar(this, bv, InsetSpecialChar::MENU_SEPARATOR);
593                 break;
594
595         case LFUN_MARK_OFF:
596                 bv->beforeChange(this);
597                 update(bv, false);
598                 selection.cursor = cursor;
599                 cmd.message(N_("Mark off"));
600                 break;
601
602         case LFUN_MARK_ON:
603                 bv->beforeChange(this);
604                 selection.mark(true);
605                 update(bv, false);
606                 selection.cursor = cursor;
607                 cmd.message(N_("Mark on"));
608                 break;
609
610         case LFUN_SETMARK:
611                 bv->beforeChange(this);
612                 if (selection.mark()) {
613                         update(bv);
614                         cmd.message(N_("Mark removed"));
615                 } else {
616                         selection.mark(true);
617                         update(bv);
618                         cmd.message(N_("Mark set"));
619                 }
620                 selection.cursor = cursor;
621                 break;
622
623         case LFUN_UPCASE_WORD:
624                 update(bv, false);
625                 changeCase(bv, LyXText::text_uppercase);
626                 if (inset_owner)
627                         bv->updateInset(inset_owner, true);
628                 update(bv);
629                 break;
630
631         case LFUN_LOWCASE_WORD:
632                 update(bv, false);
633                 changeCase(bv, LyXText::text_lowercase);
634                 if (inset_owner)
635                         bv->updateInset(inset_owner, true);
636                 update(bv);
637                 break;
638
639         case LFUN_CAPITALIZE_WORD:
640                 update(bv, false);
641                 changeCase(bv, LyXText::text_capitalization);
642                 if (inset_owner)
643                         bv->updateInset(inset_owner, true);
644                 update(bv);
645                 break;
646
647         case LFUN_TRANSPOSE_CHARS:
648                 update(bv, false);
649                 transposeChars(*bv);
650                 if (inset_owner)
651                         bv->updateInset(inset_owner, true);
652                 update(bv);
653                 break;
654
655         case LFUN_BEGINNINGBUFSEL:
656                 if (inset_owner)
657                         return Inset::UNDISPATCHED;
658                 update(bv, false);
659                 cursorTop(bv);
660                 bv->finishChange(true);
661                 break;
662
663         case LFUN_ENDBUFSEL:
664                 if (inset_owner)
665                         return Inset::UNDISPATCHED;
666                 update(bv, false);
667                 cursorBottom(bv);
668                 bv->finishChange(true);
669                 break;
670
671         case LFUN_GETXY:
672                 cmd.message(tostr(cursor.x()) + ' ' + tostr(cursor.y()));
673                 break;
674
675         case LFUN_SETXY: {
676                 int x = 0;
677                 int y = 0;
678                 if (::sscanf(cmd.argument.c_str(), " %d %d", &x, &y) != 2)
679                         lyxerr << "SETXY: Could not parse coordinates in '"
680                                << cmd.argument << std::endl;
681                 setCursorFromCoordinates(bv, x, y);
682                 break;
683         }
684
685         case LFUN_GETFONT:
686                 if (current_font.shape() == LyXFont::ITALIC_SHAPE)
687                         cmd.message("E");
688                 else if (current_font.shape() == LyXFont::SMALLCAPS_SHAPE)
689                         cmd.message("N");
690                 else
691                         cmd.message("0");
692                 break;
693
694         case LFUN_GETLAYOUT:
695                 cmd.message(tostr(cursor.par()->layout()));
696                 break;
697
698         case LFUN_LAYOUT: {
699                 lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) "
700                   << cmd.argument << endl;
701
702                 // This is not the good solution to the empty argument
703                 // problem, but it will hopefully suffice for 1.2.0.
704                 // The correct solution would be to augument the
705                 // function list/array with information about what
706                 // functions needs arguments and their type.
707                 if (cmd.argument.empty()) {
708                         cmd.errorMessage(_("LyX function 'layout' needs an argument."));
709                         break;
710                 }
711
712                 // Derive layout number from given argument (string)
713                 // and current buffer's textclass (number)
714                 LyXTextClass const & tclass = bv->buffer()->params.getLyXTextClass();
715                 bool hasLayout = tclass.hasLayout(cmd.argument);
716                 string layout = cmd.argument;
717
718                 // If the entry is obsolete, use the new one instead.
719                 if (hasLayout) {
720                         string const & obs = tclass[layout]->obsoleted_by();
721                         if (!obs.empty())
722                                 layout = obs;
723                 }
724
725                 if (!hasLayout) {
726                         cmd.errorMessage(string(N_("Layout ")) + cmd.argument +
727                                 N_(" not known"));
728                         break;
729                 }
730
731                 bool change_layout = (current_layout != layout);
732                 if (!change_layout && selection.set() &&
733                         selection.start.par() != selection.end.par())
734                 {
735                         Paragraph * spar = selection.start.par();
736                         Paragraph * epar = selection.end.par()->next();
737                         while (spar != epar) {
738                                 if (spar->layout()->name() != current_layout) {
739                                         change_layout = true;
740                                         break;
741                                 }
742                         }
743                 }
744                 if (change_layout) {
745                         bv->hideCursor();
746                         current_layout = layout;
747                         update(bv, false);
748                         setLayout(bv, layout);
749                         bv->owner()->setLayout(layout);
750                         update(bv);
751                         bv->switchKeyMap();
752                 }
753                 break;
754         }
755
756         case LFUN_PASTESELECTION: {
757                 if (!bv->buffer())
758                         break;
759                 bv->hideCursor();
760                 // this was originally a beforeChange(bv->text), i.e
761                 // the outermost LyXText!
762                 bv->beforeChange(this);
763                 string const clip(bv->workarea().getClipboard());
764                 if (!clip.empty()) {
765                         if (cmd.argument == "paragraph")
766                                 insertStringAsParagraphs(bv, clip);
767                         else
768                                 insertStringAsLines(bv, clip);
769                         clearSelection();
770                         update(bv);
771                 }
772                 break;
773         }
774
775         case LFUN_SELFINSERT: {
776                 if (cmd.argument.empty())
777                         break;
778
779                 // Automatically delete the currently selected
780                 // text and replace it with what is being
781                 // typed in now. Depends on lyxrc settings
782                 // "auto_region_delete", which defaults to
783                 // true (on).
784
785                 if (lyxrc.auto_region_delete) {
786                         if (selection.set()) {
787                                 cutSelection(bv, false, false);
788                                 update(bv);
789                         }
790                         bv->workarea().haveSelection(false);
791                 }
792
793                 bv->beforeChange(this);
794                 LyXFont const old_font(real_current_font);
795
796                 string::const_iterator cit = cmd.argument.begin();
797                 string::const_iterator end = cmd.argument.end();
798                 for (; cit != end; ++cit)
799                         bv->owner()->getIntl().getTransManager().
800                                 TranslateAndInsert(*cit, this);
801
802                 update(bv);
803                 selection.cursor = cursor;
804                 bv->moveCursorUpdate(false);
805
806                 // real_current_font.number can change so we need to
807                 // update the minibuffer
808                 if (old_font != real_current_font)
809                         bv->owner()->view_state_changed();
810                 break;
811         }
812
813         default:
814                 return Inset::UNDISPATCHED;
815         }
816
817         return Inset::DISPATCHED;
818 }