Set also txt.vy when moving the scrollbar in GTK.
[mp-5.x.git] / mp_clipboard.mpsl
blob09a36706f9e706971b0383bb387d58e01bccd573
1 /*
3     Minimum Profit 5.x
4     A Programmer's Text Editor
6     Clipboard routines.
8     Copyright (C) 1991-2007 Angel Ortega <angel@triptico.com>
10     This program is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     as published by the Free Software Foundation; either version 2
13     of the License, or (at your option) any later version.
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24     http://www.triptico.com
28 /** editor actions **/
31 mp.actions['unmark']    = sub (d) { mp.unmark(d); };
32 mp.actions['mark']      = sub (d) { mp.mark(d); };
33 mp.actions['mark_vertical'] = sub (d) { mp.mark_vertical(d); };
34 mp.actions['copy_mark'] = sub (d) {
35                                         mp.busy(1);
36                                         mp.copy(d);
37                                         mp.unmark(d);
38                                         mp.drv.clip_to_sys();
39                                         mp.busy(0);
40                                 };
42 mp.actions['paste_mark'] = sub (d) {
43                                         mp.busy(1);
44                                         mp.store_undo(d);
45                                         mp.drv.sys_to_clip();
46                                         mp.paste(d);
47                                         mp.busy(0);
48                                 };
50 mp.actions['cut_mark']  = sub (d) {
51                                         mp.busy(1);
52                                         mp.store_undo(d);
53                                         mp.cut(d);
54                                         mp.drv.clip_to_sys();
55                                         mp.busy(0);
56                                 };
58 mp.actions['mouse_drag_mark'] = sub (d) {
60         /* no selection yet? move to initial click and mark */
61         if (d.txt.mark == NULL)
62                 mp.mark(d);
64         /* move to drag position */
65         mp.move_to_coords_xy(d, mp.mouse_to_x, mp.mouse_to_y);
67         /* and mark */
68         mp.mark(d);
71 /** default key bindings **/
73 mp.keycodes['f8']               = "unmark";
74 mp.keycodes['f9']               = "mark";
75 mp.keycodes['ctrl-b']           = "mark_vertical";
76 mp.keycodes['ctrl-c']           = "copy_mark";
77 mp.keycodes['ctrl-v']           = "paste_mark";
78 mp.keycodes['ctrl-x']           = "cut_mark";
79 mp.keycodes['mouse-drag']       = "mouse_drag_mark";
81 /** action descriptions **/
83 mp.actdesc['unmark']            = LL("Unmark block");
84 mp.actdesc['mark']              = LL("Mark beginning/end of block");
85 mp.actdesc['mark_vertical']     = LL("Mark vertical block");
86 mp.actdesc['copy_mark']         = LL("Copy block");
87 mp.actdesc['paste_mark']        = LL("Paste block");
88 mp.actdesc['cut_mark']          = LL("Cut block");
89 mp.actdesc['mouse_drag_mark']   = LL("Mark using mouse dragging");
91 /** code **/
94 sub mp.unmark(doc)
95 /* unmarks the block */
97         /* just destroy the mark */
98         doc.txt.mark = NULL;
102 sub mp.mark(doc)
103 /* marks the start or end of the block */
105         local txt = doc.txt;
107         if (txt.mark == NULL) {
108                 /* no mark; create one */
109                 txt.mark = {};
110                 txt.mark.ax = txt.mark.bx = txt.mark.ex = txt.x;
111                 txt.mark.ay = txt.mark.by = txt.mark.ey = txt.y;
112                 txt.mark.vertical = 0;
113                 txt.mark.incomplete = 1;
114         }
115         else {
116                 /* mark exists; extend current one */
117                 if (txt.mark.vertical == 0) {
118                         /* normal selection */
119                         if (txt.y < txt.mark.ay ||
120                                 (txt.y == txt.mark.ay && txt.x < txt.mark.ax)) {
121                                 /* move the beginning of the block */
122                                 txt.mark.bx = txt.x;
123                                 txt.mark.by = txt.y;
124                                 txt.mark.ex = txt.mark.ax;
125                                 txt.mark.ey = txt.mark.ay;
126                         }
127                         else {
128                                 /* move the end of the block */
129                                 txt.mark.ex = txt.x;
130                                 txt.mark.ey = txt.y;
131                                 txt.mark.bx = txt.mark.ax;
132                                 txt.mark.by = txt.mark.ay;
133                         }
134                 }
135                 else {
136                         /* vertical selection */
137                         txt.mark.by = txt.mark.ay;
138                         txt.mark.ey = txt.y;
139                         if (txt.y < txt.mark.ay) {
140                                 txt.mark.by = txt.y;
141                                 txt.mark.ey = txt.mark.ay;
142                         }
144                         txt.mark.bx = txt.mark.ax;
145                         txt.mark.ex = txt.x;
146                         if (txt.x < txt.mark.ax) {
147                                 txt.mark.bx = txt.x;
148                                 txt.mark.ex = txt.mark.ax;
149                         }
150                 }
152                 txt.mark.incomplete = 0;
153         }
157 sub mp.mark_vertical(doc)
158 /* start vertical block selection */
160         mp.mark(doc);
161         doc.txt.mark.vertical = 1;
165 sub mp.get_active_area(doc)
166 /* returns the active area: the selection or the full document */
168         local m;
170         if ((m = doc.txt.mark) == NULL)
171                 return doc.txt.lines;
172         else
173                 return mp.get_range(doc, m.bx, m.by, m.ex, m.ey, m.vertical);
177 sub mp.copy(doc)
178 /* copies the mark to the clipboard */
180         if (doc.txt.mark) {
181                 mp.clipboard = mp.get_active_area(doc);
182                 mp.clipboard_vertical = doc.txt.mark.vertical;
183         }
187 sub mp.delete_mark(doc)
188 /* deletes current selection */
190         local txt = doc.txt;
192         /* no mark? done */
193         if (txt.mark == NULL)
194                 return;
196         /* deletes the range */
197         mp.delete_range(doc,
198                 txt.mark.bx, txt.mark.by, txt.mark.ex, txt.mark.ey, txt.mark.vertical);
200         mp.unmark(doc);
204 sub mp.cut(doc)
205 /* cut (copy + delete) selected mark */
207         mp.copy(doc);
208         mp.delete_mark(doc);
212 sub mp.paste(doc)
213 /* pastes from the clipboard into a text */
215         local t = mp.config.auto_indent;
216         mp.config.auto_indent = 0;
217         if (mp.clipboard_vertical == 0) {
218                 /* normal selction in clipboard */
219                 mp.insert(doc, mp.clipboard);
220         }
221         else {
222                 /* vertical selection in clipboard */
223                 local txt = doc.txt;
224                 local s = size(mp.clipboard);
225                 local i = 0;
226                 local w;
227                 local e;
228                 while (i < s) {
229                         /* pad out to current x position */
230                         e = txt.x - size(txt.lines[txt.y]);
232                         while(e-- > 0)
233                                 txt.lines[txt.y] = txt.lines[txt.y] ~ " ";
234                         
235                         /* insert this line of the clipboard */
236                         w = splice(txt.lines[txt.y], mp.clipboard[i++], txt.x, 0);
237                         txt.lines[txt.y++] = w[0];
238                 }
239                 txt.y--;
240                 txt.mod++;
241         }
242         mp.config.auto_indent = t;