+2000-03-27 Juergen Vigna <jug@sad.it>
+
+ * src/insets/insettext.C: added Cut/Copy/Paste inside insets,
+ also some modifications with operations on selected text.
+
+ * src/BufferView.C (checkInsetHit): Now hopefully fixed all the
+ problems with clicking on insets (last famous words ;)
+
+ * src/insets/insetcommand.C (draw):
+ (width): Changed to have a bit of space before and after the inset so
+ that the blinking cursor can be seen (otherwise it was hidden)
+
2000-03-22 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
* config/gettext.m4 (AM_WITH_NLS): fix a gettext bug where -lintl
if (buffer_ == 0 || !screen) return;
- Inset * inset_hit = checkInsetHit(xpos, ypos);
+ Inset * inset_hit = checkInsetHit(xpos, ypos, button);
// ok ok, this is a hack.
if (button == 4 || button == 5) {
return;
}
- text->SetCursorFromCoordinates(xpos, ypos + screen_first);
+ if (!inset_hit) // otherwise it was already set in checkInsetHit(...)
+ text->SetCursorFromCoordinates(xpos, ypos + screen_first);
text->FinishUndo();
text->sel_cursor = text->cursor;
text->cursor.x_fix = text->cursor.x;
// If we hit an inset, we have the inset coordinates in these
// and inset_hit points to the inset. If we do not hit an
// inset, inset_hit is 0, and inset_x == x, inset_y == y.
- Inset * inset_hit = checkInsetHit(x, y);
+ Inset * inset_hit = checkInsetHit(x, y, button);
if (the_locking_inset) {
// We are in inset locking mode.
* If hit, the coordinates are changed relative to the inset.
* Otherwise coordinates are not changed, and false is returned.
*/
-Inset * BufferView::checkInsetHit(int & x, int & y)
+Inset * BufferView::checkInsetHit(int & x, int & y, unsigned int button)
{
if (!screen)
return 0;
int y_tmp = y + screen->first;
- LyXCursor & old_cursor = text->cursor;
- text->SetCursorFromCoordinates(x,y);
- LyXCursor & cursor = text->cursor;
-
- bool is_rtl = text->real_current_font.isVisibleRightToLeft();
+ LyXCursor cursor;
+ text->SetCursorFromCoordinates(cursor, x, y_tmp);
+#if 1
+ bool move_cursor = true;
+#else
+ bool move_cursor = ((cursor.par != text->cursor.par) ||
+ (cursor.pos != text->cursor.pos)) && (button < 2);
+#endif
if (cursor.pos < cursor.par->Last()
&& cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
// Check whether the inset really was hit
Inset * tmpinset = cursor.par->GetInset(cursor.pos);
LyXFont font = text->GetFont(cursor.par, cursor.pos);
+ bool is_rtl = font.isVisibleRightToLeft();
int start_x, end_x;
+
if (is_rtl) {
start_x = cursor.x - tmpinset->width(painter(), font);
end_x = cursor.x;
if (x > start_x && x < end_x
&& y_tmp > cursor.y - tmpinset->ascent(painter(), font)
&& y_tmp < cursor.y + tmpinset->descent(painter(), font)) {
+ if (move_cursor)
+ text->SetCursorFromCoordinates(x, y_tmp);
x = x - start_x;
// The origin of an inset is on the baseline
- y = y_tmp - (cursor.y);
+ y = y_tmp - (text->cursor.y);
return tmpinset;
}
}
(cursor.par->GetChar(cursor.pos-1) == LyXParagraph::META_INSET) &&
(cursor.par->GetInset(cursor.pos - 1)) &&
(cursor.par->GetInset(cursor.pos - 1)->Editable())) {
- text->CursorLeft();
- Inset * tmpinset = cursor.par->GetInset(cursor.pos);
- LyXFont font = text->GetFont(cursor.par, cursor.pos);
+ Inset * tmpinset = cursor.par->GetInset(cursor.pos-1);
+ LyXFont font = text->GetFont(cursor.par, cursor.pos-1);
+ bool is_rtl = font.isVisibleRightToLeft();
int start_x, end_x;
- if (is_rtl) {
+
+ if (!is_rtl) {
start_x = cursor.x - tmpinset->width(painter(), font);
end_x = cursor.x;
} else {
if (x > start_x && x < end_x
&& y_tmp > cursor.y - tmpinset->ascent(painter(), font)
&& y_tmp < cursor.y + tmpinset->descent(painter(), font)) {
+ if (move_cursor)
+ text->SetCursorFromCoordinates(x, y_tmp);
x = x - start_x;
// The origin of an inset is on the baseline
- y = y_tmp - (cursor.y);
+ y = y_tmp - (text->cursor.y);
return tmpinset;
- } else {
- text->CursorRight();
}
}
- text->SetCursor(old_cursor.par, old_cursor.pos);
return 0;
}
///
void create_view();
///
- Inset * checkInsetHit(int & x, int & y);
+ Inset * checkInsetHit(int & x, int & y, unsigned int button);
///
int scrollUp(long time);
///
LColor::commandbg, LColor::commandframe,
false, width, ascent, descent);
}
- return width;
+ return width+4;
#else
LyXFont f = font;
f.decSize();
string s = getScreenLabel();
if (Editable()) {
- pain.buttonText(int(x), baseline, s, font, true, width);
+ pain.buttonText(int(x)+2, baseline, s, font, true, width);
} else {
- pain.rectText(int(x), baseline, s, font,
+ pain.rectText(int(x)+2, baseline, s, font,
LColor::commandbg, LColor::commandframe,
true, width);
}
- x += width;
+ x += width + 4;
#else
x += 3;
computeTextRows(pain, x);
UpdatableInset::draw(pain, f, baseline, x);
- bool do_reset_pos = (x != top_x) || (baseline != top_baseline);
top_x = int(x);
top_baseline = baseline;
computeBaselines(baseline);
drawRowText(pain, rows[r].pos, rows[r + 1].pos, rows[r].baseline, x);
}
x += insetWidth;
- if (!the_locking_inset && do_reset_pos) {
-// HideInsetCursor(bv);
-// resetPos(bv);
-// ShowInsetCursor(bv);
- }
}
switch (action) {
// Normal chars
case -1:
+ cutSelection();
+ actpos = selection_start;
par->InsertChar(actpos,arg[0]);
par->SetFont(actpos,real_current_font);
- UpdateLocal(bv, true);
++actpos;
selection_start = selection_end = actpos;
- resetPos(bv);
+ UpdateLocal(bv, true);
break;
// --- Cursor Movements ---------------------------------------------
case LFUN_RIGHTSEL:
}
moveLeft(bv);
case LFUN_DELETE:
- if (Delete()) { // we need update
+ bool ret;
+ if (hasSelection())
+ ret = cutSelection();
+ else
+ ret = Delete();
+ if (ret) { // we need update
+ selection_start = selection_end = actpos;
+ UpdateLocal(bv, true);
+ } else if (hasSelection()) {
+ selection_start = selection_end = actpos;
+ UpdateLocal(bv, false);
+ }
+ break;
+ case LFUN_CUT:
+ if (cutSelection()) { // we need update
+ actpos = selection_end = selection_start;
+ UpdateLocal(bv, true);
+ } else if (hasSelection()) {
+ selection_start = selection_end = actpos;
+ UpdateLocal(bv, false);
+ }
+ break;
+ case LFUN_COPY:
+ if (copySelection()) { // we need update
selection_start = selection_end = actpos;
UpdateLocal(bv, true);
} else if (hasSelection()) {
UpdateLocal(bv, false);
}
break;
+ case LFUN_PASTE:
+ if (pasteSelection()) {
+ selection_start = selection_end = actpos;
+ UpdateLocal(bv, true);
+ }
+ break;
case LFUN_HOME:
for(; actpos > rows[actrow].pos; --actpos)
cx -= SingleWidth(bv->getPainter(), par, actpos);
void InsetText::resetPos(BufferView * bv)
{
+ if (!rows.size())
+ return;
+
int old_pos = actpos;
cy = top_baseline;
/* some insets are undeletable here */
if (par->GetChar(actpos)==LyXParagraph::META_INSET) {
/* force complete redo when erasing display insets */
- /* this is a cruel mathod but save..... Matthias */
+ /* this is a cruel method but save..... Matthias */
if (par->GetInset(actpos)->Deletable() &&
par->GetInset(actpos)->display()) {
par->Erase(actpos);
void InsetText::UpdateLocal(BufferView *bv, bool flag)
{
- init_inset = flag;
+ HideInsetCursor(bv);
+ if (flag) {
+ computeTextRows(bv->painter(), xpos);
+ computeBaselines(top_baseline);
+ resetPos(bv);
+ }
bv->updateInset(this, flag);
+ ShowInsetCursor(bv);
+}
+
+// this is for the simple cut and paste mechanism
+// this then should be a global stuff so that cut'n'paste can work in and
+// and outside text-insets
+static LyXParagraph * simple_cut_buffer = 0;
+// static char simple_cut_buffer_textclass = 0;
+
+// for now here this should be in another Cut&Paste Class!
+//
+static void DeleteSimpleCutBuffer()
+{
+ if (!simple_cut_buffer)
+ return;
+ LyXParagraph * tmppar;
+
+ while (simple_cut_buffer) {
+ tmppar = simple_cut_buffer;
+ simple_cut_buffer = simple_cut_buffer->next;
+ delete tmppar;
+ }
+ simple_cut_buffer = 0;
+}
+
+bool InsetText::cutSelection()
+{
+ if (!hasSelection())
+ return false;
+ DeleteSimpleCutBuffer();
+
+ // only within one paragraph
+ simple_cut_buffer = new LyXParagraph;
+ LyXParagraph::size_type i = selection_start;
+ for (; i < selection_end; ++i) {
+ par->CopyIntoMinibuffer(selection_start);
+ par->Erase(selection_start);
+ simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
+ }
+ return true;
+}
+
+bool InsetText::copySelection()
+{
+ if (!hasSelection())
+ return false;
+ DeleteSimpleCutBuffer();
+
+ // only within one paragraph
+ simple_cut_buffer = new LyXParagraph;
+ LyXParagraph::size_type i = selection_start;
+ for (; i < selection_end; ++i) {
+ par->CopyIntoMinibuffer(i);
+ simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
+ }
+ return true;
+}
+
+bool InsetText::pasteSelection()
+{
+ if (!simple_cut_buffer)
+ return false;
+
+ LyXParagraph * tmppar = simple_cut_buffer->Clone();
+
+ while (simple_cut_buffer->size()) {
+ simple_cut_buffer->CutIntoMinibuffer(0);
+ simple_cut_buffer->Erase(0);
+ par->InsertFromMinibuffer(actpos);
+ ++actpos;
+ }
+ delete simple_cut_buffer;
+ simple_cut_buffer = tmppar;
+ return true;
}
bool moveUp(BufferView *, bool activate_inset = true);
bool moveDown(BufferView *, bool activate_inset = true);
bool Delete();
+ bool cutSelection();
+ bool copySelection();
+ bool pasteSelection();
///
bool hasSelection() const { return selection_start != selection_end; }
///
bool setfont = true) const;
///
void SetCursorFromCoordinates(int x, long y) const;
+ void SetCursorFromCoordinates(LyXCursor &, int x, long y) const;
///
void CursorUp() const;
///
DeleteEmptyParagraphMechanism(old_cursor);
}
+void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
+{
+ /* get the row first */
+
+ Row * row = GetRowNearY(y);
+ int column = GetColumnNearX(row, x);
+
+ cur.par = row->par;
+ cur.pos = row->pos + column;
+ cur.x = x;
+ cur.y = y + row->baseline;
+ cur.row = row;
+}
+
void LyXText::CursorLeft() const
{