]> git.lyx.org Git - lyx.git/blobdiff - src/text3.C
remove broken xpm
[lyx.git] / src / text3.C
index f4a50ab3e36242533c6208cb28710d6d98c03d90..b620c11e71143e39b4b4255989c0dca7623d3dcf 100644 (file)
 #include "gettext.h"
 #include "factory.h"
 #include "intl.h"
+#include "box.h"
 #include "language.h"
 #include "support/lstrings.h"
 #include "frontends/LyXView.h"
 #include "frontends/screen.h"
-#include "frontends/WorkArea.h"
+#include "frontends/Dialogs.h"
 #include "insets/insetspecialchar.h"
 #include "insets/insettext.h"
 #include "insets/insetbib.h"
@@ -74,7 +75,7 @@ namespace {
                }
 
                if (!lt->selection.set())
-                       bv->workarea().haveSelection(false);
+                       bv->haveSelection(false);
 
                bv->switchKeyMap();
        }
@@ -87,6 +88,81 @@ namespace {
                bv->owner()->view_state_changed();
        }
 
+       // check if the given co-ordinates are inside an inset at the
+       // given cursor, if one exists. If so, the inset is returned,
+       // and the co-ordinates are made relative. Otherwise, 0 is returned.
+       Inset * checkInset(BufferView * bv, LyXText const & text,
+               LyXCursor const & cur, int & x, int & y)
+       {
+               lyx::pos_type const pos = cur.pos();
+               Paragraph /*const*/ & par = *cur.par();
+
+               if (pos >= par.size() || !par.isInset(pos))
+                       return 0;
+
+               Inset /*const*/ * inset = par.getInset(pos);
+
+               if (!isEditableInset(inset)) 
+                       return 0;
+
+               // get inset dimensions
+               lyx::Assert(par.getInset(pos));
+
+               LyXFont const & font = text.getFont(bv->buffer(), &par, pos);
+
+               int const width = inset->width(bv, font);
+               int const inset_x = font.isVisibleRightToLeft()
+                       ? (cur.ix() - width) : cur.ix();
+
+               Box b(
+                       inset_x + inset->scroll(),
+                       inset_x + width,
+                       cur.iy() - inset->ascent(bv, font),
+                       cur.iy() + inset->descent(bv, font)
+               );
+
+               if (!b.contained(x, y)) {
+                       lyxerr[Debug::GUI] << "Missed inset at x,y " << x << "," << y
+                               << " box " << b << endl;
+                       return 0;
+               }
+
+               text.setCursor(bv, &par, pos, true);
+
+               x -= b.x1;
+               // The origin of an inset is on the baseline
+               y -= text.cursor.iy();
+
+               return inset;
+       }
+
+} // anon namespace
+
+
+Inset * LyXText::checkInsetHit(BufferView * bv, int & x, int & y) const
+{
+       int y_tmp = y + first_y;
+
+       LyXCursor cur;
+       setCursorFromCoordinates(bv, cur, x, y_tmp);
+
+       Inset * inset = checkInset(bv, *this, cur, x, y_tmp);
+       if (inset) {
+               y = y_tmp;
+               return inset;
+       }
+
+       // look at previous position
+       if (cur.pos() == 0)
+               return 0;
+
+       // move back one
+       setCursor(bv, cur, cur.par(), cur.pos() - 1, true);
+
+       inset = checkInset(bv, *this, cur, x, y_tmp);
+       if (inset)
+               y = y_tmp;
+       return inset;
 }
 
 
@@ -164,7 +240,7 @@ void LyXText::cursorPrevious(BufferView * bv)
 {
        if (!cursor.row()->previous()) {
                if (first_y > 0) {
-                       int new_y = bv->text->first_y - bv->workarea().workHeight();
+                       int new_y = bv->text->first_y - bv->workHeight();
                        bv->screen().draw(bv->text, bv, new_y < 0 ? 0 : new_y);
                        bv->updateScrollbar();
                }
@@ -184,18 +260,18 @@ void LyXText::cursorPrevious(BufferView * bv)
                // as we move the cursor or do something while inside the row (it may
                // span several workarea-heights) we'll move to the top again, but this
                // is better than just jump down and only display part of the row.
-               new_y = bv->text->first_y - bv->workarea().workHeight();
+               new_y = bv->text->first_y - bv->workHeight();
        } else {
                if (inset_owner) {
                        new_y = bv->text->cursor.iy()
                                + bv->theLockingInset()->insetInInsetY() + y
                                + cursor.row()->height()
-                               - bv->workarea().workHeight() + 1;
+                               - bv->workHeight() + 1;
                } else {
                        new_y = cursor.y()
                                - cursor.row()->baseline()
                                + cursor.row()->height()
-                               - bv->workarea().workHeight() + 1;
+                               - bv->workHeight() + 1;
                }
        }
        bv->screen().draw(bv->text, bv, new_y < 0 ? 0 : new_y);
@@ -216,15 +292,15 @@ void LyXText::cursorNext(BufferView * bv)
        if (!cursor.row()->next()) {
                int y = cursor.y() - cursor.row()->baseline() +
                        cursor.row()->height();
-               if (y > int(first_y + bv->workarea().workHeight())) {
+               if (y > int(first_y + bv->workHeight())) {
                        bv->screen().draw(bv->text, bv,
-                                                 bv->text->first_y + bv->workarea().workHeight());
+                                                 bv->text->first_y + bv->workHeight());
                        bv->updateScrollbar();
                }
                return;
        }
 
-       int y = first_y + bv->workarea().workHeight();
+       int y = first_y + bv->workHeight();
        if (inset_owner && !first_y) {
                y -= (bv->text->cursor.iy()
                          - bv->text->first_y
@@ -235,7 +311,7 @@ void LyXText::cursorNext(BufferView * bv)
 
        Row * cursorrow = cursor.row();
        setCursorFromCoordinates(bv, cursor.x_fix(), y);
-       // + workarea().workHeight());
+       // + bv->workHeight());
        finishUndo();
 
        int new_y;
@@ -245,7 +321,7 @@ void LyXText::cursorNext(BufferView * bv)
                // as we move the cursor or do something while inside the row (it may
                // span several workarea-heights) we'll move to the top again, but this
                // is better than just jump down and only display part of the row.
-               new_y = bv->text->first_y + bv->workarea().workHeight();
+               new_y = bv->text->first_y + bv->workHeight();
        } else {
                if (inset_owner) {
                        new_y = bv->text->cursor.iy()
@@ -260,7 +336,7 @@ void LyXText::cursorNext(BufferView * bv)
                LyXCursor cur;
                setCursor(bv, cur, cursor.row()->next()->par(),
                                                cursor.row()->next()->pos(), false);
-               if (cur.y() < int(first_y + bv->workarea().workHeight())) {
+               if (cur.y() < int(first_y + bv->workHeight())) {
                        cursorDown(bv, true);
                }
        }
@@ -1035,7 +1111,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                // this was originally a beforeChange(bv->text), i.e
                // the outermost LyXText!
                bv->beforeChange(this);
-               string const clip = bv->workarea().getClipboard();
+               string const clip = bv->getClipboard();
                if (!clip.empty()) {
                        if (cmd.argument == "paragraph")
                                insertStringAsParagraphs(bv, clip);
@@ -1064,40 +1140,6 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                break;
        }
 
-#if 0
-       case LFUN_INSET_LIST:
-       case LFUN_INSET_THEOREM:
-#endif
-       case LFUN_INSERT_NOTE:
-       case LFUN_INSET_ERT:
-       case LFUN_INSET_EXTERNAL:
-       case LFUN_INSET_FLOAT:
-       case LFUN_INSET_FOOTNOTE:
-       case LFUN_INSET_MARGINAL:
-       case LFUN_INSET_MINIPAGE:
-       case LFUN_INSET_OPTARG:
-       case LFUN_INSET_WIDE_FLOAT:
-       case LFUN_TABULAR_INSERT:
-       {
-               Inset * inset = createInset(cmd);
-               if (inset) {
-                       bool gotsel = false;
-                       if (selection.set()) {
-                               cutSelection(bv, true, false);
-                               gotsel = true;
-                       }
-                       if (bv->insertInset(inset)) {
-                               inset->edit(bv);
-                               if (gotsel)
-                                       bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION));
-                       }
-                       else
-                               delete inset;
-               }
-               break;
-       }
-
-
        case LFUN_QUOTE: {
                Paragraph const * par = cursor.par();
                lyx::pos_type pos = cursor.pos();
@@ -1159,7 +1201,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                        if (bv_owner)
                                bv->screen().toggleSelection(this, bv, false);
                        update(bv, false);
-                       bv->workarea().haveSelection(selection.set());
+                       bv->haveSelection(selection.set());
                }
                break;
 
@@ -1178,7 +1220,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                                selectWord(bv, LyXText::WHOLE_WORD_STRICT);
                        }
                        update(bv, false);
-                       bv->workarea().haveSelection(selection.set());
+                       bv->haveSelection(selection.set());
                }
                break;
 
@@ -1202,8 +1244,8 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                                ? cursor.ix() - width : cursor.ix();
                        int start_x = inset_x + tli->scroll();
                        FuncRequest cmd1 = cmd;
-                       cmd1.x -= start_x;
-                       cmd1.y -= cursor.iy() + bv->text->first_y;
+                       cmd1.x = cmd.x - start_x;
+                       cmd1.y = cmd.y - cursor.iy() + bv->text->first_y;
                        tli->localDispatch(cmd1);
                        break;
                }
@@ -1231,16 +1273,15 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
        #endif
                // This is to allow jumping over large insets
                if (cursorrow == bv->text->cursor.row()) {
-                       if (cmd.y >= int(bv->workarea().workHeight())) {
+                       if (cmd.y >= int(bv->workHeight()))
                                bv->text->cursorDown(bv, false);
-                       } else if (cmd.y < 0) {
+                       else if (cmd.y < 0)
                                bv->text->cursorUp(bv, false);
-                       }
                }
 
+               // Maybe an empty line was deleted
                if (!bv->text->selection.set())
-                       bv->update(bv->text, BufferView::UPDATE); // Maybe an empty line was deleted
-
+                       bv->update(bv->text, BufferView::UPDATE);
                bv->text->setSelection(bv);
                bv->screen().toggleToggle(bv->text, bv);
                bv->fitCursor();
@@ -1269,7 +1310,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
 
                int x = cmd.x;
                int y = cmd.y;
-               Inset * inset_hit = bv->checkInsetHit(bv->text, x, y);
+               Inset * inset_hit = bv->text->checkInsetHit(bv, x, y);
 
                // Middle button press pastes if we have a selection
                // We do this here as if the selection was inside an inset
@@ -1289,8 +1330,8 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                        // Check whether the inset was hit. If not reset mode,
                        // otherwise give the event to the inset
                        if (inset_hit == bv->theLockingInset()) {
-                               FuncRequest cmd(bv, LFUN_MOUSE_PRESS, x, y, cmd.button());
-                               bv->theLockingInset()->localDispatch(cmd);
+                               FuncRequest cmd1(bv, LFUN_MOUSE_PRESS, x, y, cmd.button());
+                               bv->theLockingInset()->localDispatch(cmd1);
                                break;
                        }
                        bv->unlockInset(bv->theLockingInset());
@@ -1319,8 +1360,8 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                        // we don't need the edit() call here! (Jug20020329)
                        if (!bv->lockInset(inset))
                                lyxerr[Debug::INSETS] << "Cannot lock inset" << endl;
-                       FuncRequest cmd(bv, LFUN_MOUSE_PRESS, x, y, cmd.button());
-                       inset->localDispatch(cmd);
+                       FuncRequest cmd1(bv, LFUN_MOUSE_PRESS, x, y, cmd.button());
+                       inset->localDispatch(cmd1);
                        break;
                }
                // I'm not sure we should continue here if we hit an inset (Jug20020403)
@@ -1369,7 +1410,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                // inset, inset_hit is 0, and inset_x == x, inset_y == y.
                int x = cmd.x;
                int y = cmd.y;
-               Inset * inset_hit = bv->checkInsetHit(bv->text, x, y);
+               Inset * inset_hit = bv->text->checkInsetHit(bv, x, y);
 
                if (bv->theLockingInset()) {
                        // We are in inset locking mode.
@@ -1377,8 +1418,8 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                        // LyX does a kind of work-area grabbing for insets.
                        // Only a ButtonPress FuncRequest outside the inset will
                        // force a insetUnlock.
-                       FuncRequest cmd(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
-                       bv->theLockingInset()->localDispatch(cmd);
+                       FuncRequest cmd1(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
+                       bv->theLockingInset()->localDispatch(cmd1);
                        break;
                }
 
@@ -1389,7 +1430,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
 
                // finish selection
                if (cmd.button() == mouse_button::button1)
-                       bv->workarea().haveSelection(selection.set());
+                       bv->haveSelection(selection.set());
 
                bv->switchKeyMap();
                bv->owner()->view_state_changed();
@@ -1437,11 +1478,11 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                        if (isHighlyEditableInset(inset_hit)) {
                                // Highly editable inset, like math
                                UpdatableInset * inset = (UpdatableInset *) inset_hit;
-                               FuncRequest cmd(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
-                               inset->localDispatch(cmd);
+                               FuncRequest cmd1(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
+                               inset->localDispatch(cmd1);
                        } else {
-                               FuncRequest cmd(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
-                               inset_hit->localDispatch(cmd);
+                               FuncRequest cmd1(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
+                               inset_hit->localDispatch(cmd1);
                                // IMO this is a grosshack! Inset's should be changed so that
                                // they call the actions they have to do with the insetButtonRel.
                                // function and not in the edit(). This should be changed
@@ -1483,7 +1524,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                                cutSelection(bv, false, false);
                                update(bv);
                        }
-                       bv->workarea().haveSelection(false);
+                       bv->haveSelection(false);
                }
 
                bv->beforeChange(this);
@@ -1506,6 +1547,59 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
                break;
        }
 
+       case LFUN_HTMLURL: {
+               InsetCommandParams p("htmlurl");
+               bv->owner()->getDialogs().createUrl(p.getAsString());
+               break;
+       }
+
+       case LFUN_URL: {
+               InsetCommandParams p("url");
+               bv->owner()->getDialogs().createUrl(p.getAsString());
+               break;
+       }
+
+
+#if 0
+       case LFUN_INSET_LIST:
+       case LFUN_INSET_THEOREM:
+#endif
+       case LFUN_INSERT_NOTE:
+       case LFUN_INSERT_URL:
+       case LFUN_INSET_CAPTION:
+       case LFUN_INSET_ERT:
+       case LFUN_INSET_EXTERNAL:
+       case LFUN_INSET_FLOAT:
+       case LFUN_INSET_FOOTNOTE:
+       case LFUN_INSET_MARGINAL:
+       case LFUN_INSET_MINIPAGE:
+       case LFUN_INSET_OPTARG:
+       case LFUN_INSET_WIDE_FLOAT:
+       case LFUN_TABULAR_INSERT:
+       case LFUN_INDEX_INSERT:
+       case LFUN_INDEX_PRINT: 
+       case LFUN_PARENTINSERT:
+       case LFUN_TOC_INSERT:
+       {
+               Inset * inset = createInset(cmd);
+               if (inset) {
+                       bool gotsel = false;
+                       if (selection.set()) {
+                               cutSelection(bv, true, false);
+                               gotsel = true;
+                       }
+                       if (bv->insertInset(inset)) {
+                               inset->edit(bv);
+                               if (gotsel)
+                                       bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION));
+                       }
+                       else
+                               delete inset;
+               }
+               break;
+       }
+
+
        default:
                return Inset::UNDISPATCHED;
        }