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