1 /*
2 
3     Minimum Profit - A Text Editor
4     Code common to Qt4 and KDE4 drivers.
5 
6     ttcdt <dev@triptico.com> et al.
7 
8     This software is released into the public domain.
9     NO WARRANTY. See file LICENSE for details.
10 
11 */
12 
13 class MPArea : public QWidget
14 {
15     Q_OBJECT
16 
17 public:
18     MPArea(QWidget * parent = 0);
19     void inputMethodEvent(QInputMethodEvent * event);
20     void keyPressEvent(QKeyEvent * event);
21     void keyReleaseEvent(QKeyEvent * event);
22     void mousePressEvent(QMouseEvent * event);
23     void mouseDoubleClickEvent(QMouseEvent * event);
24     void mouseReleaseEvent(QMouseEvent * event);
25     void mouseMoveEvent(QMouseEvent * event);
26     void wheelEvent(QWheelEvent * event);
27     void dragEnterEvent(QDragEnterEvent * event);
28     void dropEvent(QDropEvent * event);
29     bool event(QEvent * event);
30 
31     void draw_scrollbar();
32     void draw_status();
33     void draw_filetabs();
34 
35     QFont *font;
36 
37     QScrollBar *scrollbar;
38     QLabel *statusbar;
39     QTabBar *file_tabs;
40 
41     QTimer *timer;
42 
43     QPixmap *pixmap;
44     int ls_width;
45     int ls_height;
46     int ignore_scrollbar_signal;
47     int mouse_down;
48     qreal font_width;
49     qreal font_height;
50 
51 protected:
52     void paintEvent(QPaintEvent * event);
53 
54 public slots:
55     void from_scrollbar(int);
56     void from_filetabs(int);
57     void from_menu(QAction *);
58     void from_timer(void);
59 };
60 
61 
62 /* hash of qactions to MP actions */
63 QHash <QAction *, mpdm_t> qaction_to_action;
64 
65 
66 /** code **/
67 
qstring_to_v(QString s)68 static mpdm_t qstring_to_v(QString s)
69 /* converts a QString to an MPDM string */
70 {
71     mpdm_t r = NULL;
72 
73     if (s != NULL) {
74         int t = s.size();
75         wchar_t *wptr = (wchar_t *) calloc((t + 1), sizeof(wchar_t));
76 
77         r = MPDM_ENS(wptr, t);
78 
79         s.toWCharArray(wptr);
80     }
81 
82     return r;
83 }
84 
85 
v_to_qstring(mpdm_t s)86 QString v_to_qstring(mpdm_t s)
87 /* converts an MPDM string to a QString */
88 {
89     return QString::fromWCharArray(mpdm_string(s));
90 }
91 
92 
93 #define MAX_COLORS 100
94 QPen inks[MAX_COLORS];
95 QBrush papers[MAX_COLORS];
96 bool underlines[MAX_COLORS];
97 int normal_attr = 0;
98 
qk_build_colors(void)99 static void qk_build_colors(void)
100 /* builds the colors */
101 {
102     mpdm_t colors;
103     mpdm_t v, i;
104     int n, c;
105 
106     /* gets the color definitions and attribute names */
107     colors = mpdm_get_wcs(MP, L"colors");
108 
109     /* loop the colors */
110     n = c = 0;
111     while (mpdm_iterator(colors, &c, &v, &i)) {
112         int rgbi, rgbp;
113         mpdm_t w = mpdm_get_wcs(v, L"gui");
114 
115         /* store the 'normal' attribute */
116         if (wcscmp(mpdm_string(i), L"normal") == 0)
117             normal_attr = n;
118 
119         /* store the attr */
120         mpdm_set_wcs(v, MPDM_I(n), L"attr");
121 
122         rgbi = mpdm_ival(mpdm_get_i(w, 0));
123         rgbp = mpdm_ival(mpdm_get_i(w, 1));
124 
125         /* flags */
126         w = mpdm_get_wcs(v, L"flags");
127 
128         if (mpdm_seek_wcs(w, L"reverse", 1) != -1) {
129             int t = rgbi;
130             rgbi = rgbp;
131             rgbp = t;
132         }
133 
134         underlines[n] = mpdm_seek_wcs(w, L"underline", 1) != -1 ? true : false;
135 
136         inks[n] = QPen(QColor::fromRgbF((float) ((rgbi & 0x00ff0000) >> 16) / 256.0,
137                                         (float) ((rgbi & 0x0000ff00) >> 8)  / 256.0,
138                                         (float) ((rgbi & 0x000000ff)) / 256.0, 1));
139 
140         papers[n] = QBrush(QColor::fromRgbF((float) ((rgbp & 0x00ff0000) >> 16) / 256.0,
141                                             (float) ((rgbp & 0x0000ff00) >> 8) / 256.0,
142                                             (float) ((rgbp & 0x000000ff)) / 256.0, 1));
143 
144         n++;
145     }
146 }
147 
148 
qk_build_font(void)149 static QFont *qk_build_font(void)
150 /* (re)builds the font */
151 {
152     QFont *font;
153     mpdm_t c;
154     mpdm_t w = NULL;
155     int font_size       = 10;
156     char *font_face     = (char *) "Courier";
157     double font_weight  = 0.0;
158 
159     if ((c = mpdm_get_wcs(MP, L"config")) != NULL) {
160         mpdm_t v;
161 
162         if ((v = mpdm_get_wcs(c, L"font_size")) != NULL)
163             font_size = mpdm_ival(v);
164         else
165             mpdm_set_wcs(c, MPDM_I(font_size), L"font_size");
166 
167         if ((v = mpdm_get_wcs(c, L"font_weight")) != NULL)
168             font_weight = mpdm_rval(v) * 100.0;
169         else
170             mpdm_set_wcs(c, MPDM_R(font_weight / 100.0), L"font_weight");
171 
172         if ((v = mpdm_get_wcs(c, L"font_face")) != NULL) {
173             w = mpdm_ref(MPDM_2MBS((wchar_t *) v->data));
174             font_face = (char *) w->data;
175         }
176         else
177             mpdm_set_wcs(c, MPDM_MBS(font_face), L"font_face");
178     }
179 
180     font = new QFont(QString(font_face), font_size);
181     font->setStyleHint(QFont::TypeWriter);
182 
183     font->setFixedPitch(true);
184 
185     if (font_weight > 0.0)
186         font->setWeight((int) font_weight);
187 
188     mpdm_unref(w);
189 
190     return font;
191 }
192 
193 
qk_build_menu(MENUBAR_CLASS * menubar)194 static void qk_build_menu(MENUBAR_CLASS *menubar)
195 /* builds the menu */
196 {
197     int n;
198     mpdm_t m;
199 
200     /* gets the current menu */
201     m = mpdm_get_wcs(MP, L"menu");
202 
203     menubar->clear();
204 
205     for (n = 0; n < (int) mpdm_size(m); n++) {
206         mpdm_t mi;
207         mpdm_t v;
208         int i;
209 
210         /* get the label */
211         mi = mpdm_get_i(m, n);
212         v = mpdm_get_i(mi, 0);
213 
214         MENU_CLASS *menu = menubar->addMenu(v_to_qstring(mpdm_gettext(v)));
215 
216         /* get the items */
217         v = mpdm_get_i(mi, 1);
218 
219         for (i = 0; i < (int) mpdm_size(v); i++) {
220             wchar_t *wptr;
221             mpdm_t w = mpdm_get_i(v, i);
222 
223             wptr = mpdm_string(w);
224 
225             if (*wptr == L'-')
226                 menu->addSeparator();
227             else {
228                 mpdm_ref(w);
229                 qaction_to_action[menu->addAction(v_to_qstring(mp_menu_label(w)))] = w;
230             }
231         }
232     }
233 
234     menubar->show();
235 }
236 
237 
238 /** MPArea methods **/
239 
MPArea(QWidget * parent)240 MPArea::MPArea(QWidget *parent) : QWidget(parent)
241 {
242     font = qk_build_font();
243 
244     setAttribute(Qt::WA_InputMethodEnabled, true);
245 
246     setAcceptDrops(true);
247 
248     timer = new QTimer();
249     connect(timer, SIGNAL(timeout()), this, SLOT(from_timer()));
250 
251     ls_width    = -1;
252     ls_height   = -1;
253 
254     scrollbar = new QScrollBar();
255     scrollbar->setFocusPolicy(Qt::NoFocus);
256 
257     statusbar = new QLabel();
258 
259     file_tabs = new QTabBar();
260     file_tabs->setFocusPolicy(Qt::NoFocus);
261 
262     ignore_scrollbar_signal = 0;
263     mouse_down = 0;
264 
265     font_width = font_height = -1;
266 }
267 
268 
event(QEvent * event)269 bool MPArea::event(QEvent *event)
270 {
271     /* special tab processing */
272     if (event->type() == QEvent::KeyPress) {
273         QKeyEvent *ke = (QKeyEvent *) event;
274 
275         if (ke->key() == Qt::Key_Tab) {
276             mp_process_event(MPDM_S(L"tab"));
277             update();
278             return true;
279         }
280         else
281         if (ke->key() == Qt::Key_Backtab) {
282             mp_process_event(MPDM_S(L"shift-tab"));
283             update();
284             return true;
285         }
286     }
287 
288     /* keep normal processing */
289     return QWidget::event(event);
290 }
291 
292 
draw_scrollbar(void)293 void MPArea::draw_scrollbar(void)
294 {
295     static int ol  = -1;
296     static int ovy = -1;
297     static int oty = -1;
298     mpdm_t txt     = mpdm_get_wcs(mp_active(), L"txt");
299     mpdm_t window  = mpdm_get_wcs(MP, L"window");
300     int vy         = mpdm_ival(mpdm_get_wcs(txt, L"vy"));
301     int ty         = mpdm_ival(mpdm_get_wcs(window, L"ty"));
302     int l          = mpdm_size(mpdm_get_wcs(txt, L"lines")) - ty;
303 
304     if (ol != l || ovy != vy || oty != ty) {
305         ignore_scrollbar_signal = 1;
306 
307         scrollbar->setMinimum(0);
308         scrollbar->setMaximum(ol = l);
309         scrollbar->setValue(ovy = vy);
310         scrollbar->setPageStep(oty = ty);
311 
312         ignore_scrollbar_signal = 0;
313     }
314 }
315 
316 
draw_status(void)317 void MPArea::draw_status(void)
318 {
319     statusbar->setText(v_to_qstring(mp_build_status_line()));
320 }
321 
322 
draw_filetabs(void)323 void MPArea::draw_filetabs(void)
324 {
325     static mpdm_t prev = NULL;
326     mpdm_t names;
327     int n, i;
328 
329     names = mpdm_ref(mp_get_doc_names());
330 
331     /* get mp.active_i now, because it can be changed
332        from the signal handler */
333     i = mpdm_ival(mpdm_get_wcs(MP, L"active_i"));
334 
335     /* is the list different from the previous one? */
336     if (mpdm_cmp(names, prev) != 0) {
337         while (file_tabs->count())
338             file_tabs->removeTab(0);
339 
340         /* create the new ones */
341         for (n = 0; n < (int) mpdm_size(names); n++)
342             file_tabs->addTab(v_to_qstring(mpdm_get_i(names, n)));
343 
344         /* store for the next time */
345         mpdm_store(&prev, names);
346     }
347 
348     mpdm_unref(names);
349 
350     /* set the active one */
351     file_tabs->setCurrentIndex(i);
352 }
353 
354 
paintEvent(QPaintEvent *)355 void MPArea::paintEvent(QPaintEvent *)
356 {
357     mpdm_t w;
358     int n, m, y, yb;
359     bool underline = false;
360     QPen *epen;
361     int is_new = 0;
362 
363     if (this->width() != ls_width && this->height() != ls_height) {
364         ls_width    = this->width();
365         ls_height   = this->height();
366         pixmap      = new QPixmap(ls_width, ls_height);
367         is_new      = 1;
368     }
369 
370     epen = new QPen(inks[normal_attr]);
371     epen->setStyle(Qt::NoPen);
372 
373     QPainter painter(pixmap);
374 
375     if (is_new) {
376         painter.setPen(*epen);
377         painter.setBrush(papers[normal_attr]);
378         painter.drawRect(0, 0, ls_width, ls_height);
379     }
380 
381     font->setUnderline(false);
382     painter.setFont(*font);
383 
384     QFontMetricsF fm(*font);
385 
386     font_width = fm.averageCharWidth();
387     font_height = fm.height();
388 
389     /* calculate window size */
390     w = mpdm_get_wcs(MP, L"window");
391     mpdm_set_wcs(w, MPDM_I(this->width() / font_width),   L"tx");
392     mpdm_set_wcs(w, MPDM_I(this->height() / font_height), L"ty");
393 
394     w = mp_draw(mp_active(), !is_new);
395 
396     yb = painter.fontMetrics().ascent() + 1;
397     y = 0;
398 
399     painter.setBackgroundMode(Qt::OpaqueMode);
400 
401     mpdm_ref(w);
402     mpdm_push(w, MPDM_A(0));
403 
404     for (n = 0; n < (int) mpdm_size(w); n++) {
405         mpdm_t l = mpdm_get_i(w, n);
406         qreal x = 0;
407 
408         if (l != NULL) {
409             painter.setPen(*epen);
410             painter.setBrush(papers[normal_attr]);
411             painter.drawRect(x, y + 1, ls_width - x, font_height);
412 
413             for (m = 0; m < (int) mpdm_size(l); m++) {
414                 int attr;
415                 mpdm_t s;
416 
417                 /* get the attribute and the string */
418                 attr = mpdm_ival(mpdm_get_i(l, m++));
419                 s = mpdm_get_i(l, m);
420 
421                 painter.setPen(inks[attr]);
422                 painter.setBackground(papers[attr]);
423 
424                 QString qs = v_to_qstring(s);
425 
426                 if (underline != underlines[attr]) {
427                     underline = underlines[attr];
428                     font->setUnderline(underline);
429                     painter.setFont(*font);
430                 }
431 
432                 painter.drawText(x, y + yb, qs);
433 
434 #ifdef CONFOPT_QT5
435                 x += fm.horizontalAdvance(qs);
436 #else
437                 x += fm.width(qs);
438 #endif
439             }
440         }
441 
442         y += font_height;
443     }
444 
445     mpdm_unref(w);
446 
447     QPainter painter2(this);
448     painter2.drawPixmap(0, 0, ls_width, ls_height, *pixmap);
449 
450     draw_filetabs();
451     draw_scrollbar();
452     draw_status();
453 
454     setFocus(Qt::OtherFocusReason);
455 }
456 
457 
inputMethodEvent(QInputMethodEvent * event)458 void MPArea::inputMethodEvent(QInputMethodEvent *event)
459 {
460     QString s = event->commitString();
461 
462     mp_process_event(qstring_to_v(s));
463     update();
464 }
465 
466 
keyReleaseEvent(QKeyEvent * event)467 void MPArea::keyReleaseEvent(QKeyEvent *event)
468 {
469     if (!event->isAutoRepeat()) {
470     }
471 }
472 
473 
keyPressEvent(QKeyEvent * event)474 void MPArea::keyPressEvent(QKeyEvent *event)
475 {
476     mpdm_t k = NULL;
477     wchar_t *ptr = NULL;
478 
479     /* set mp.shift_pressed */
480     if (event->modifiers() & Qt::ShiftModifier)
481         mpdm_set_wcs(MP, MPDM_I(1), L"shift_pressed");
482 
483     if (event->modifiers() & Qt::ShiftModifier) {
484         switch (event->key()) {
485         case Qt::Key_F1:
486             ptr = (wchar_t *) L"shift-f1";
487             break;
488         case Qt::Key_F2:
489             ptr = (wchar_t *) L"shift-f2";
490             break;
491         case Qt::Key_F3:
492             ptr = (wchar_t *) L"shift-f3";
493             break;
494         case Qt::Key_F4:
495             ptr = (wchar_t *) L"shift-f4";
496             break;
497         case Qt::Key_F5:
498             ptr = (wchar_t *) L"shift-f5";
499             break;
500         case Qt::Key_F6:
501             ptr = (wchar_t *) L"shift-f6";
502             break;
503         case Qt::Key_F7:
504             ptr = (wchar_t *) L"shift-f7";
505             break;
506         case Qt::Key_F8:
507             ptr = (wchar_t *) L"shift-f8";
508             break;
509         case Qt::Key_F9:
510             ptr = (wchar_t *) L"shift-f9";
511             break;
512         case Qt::Key_F10:
513             ptr = (wchar_t *) L"shift-f10";
514             break;
515         case Qt::Key_F11:
516             ptr = (wchar_t *) L"shift-f11";
517             break;
518         case Qt::Key_F12:
519             ptr = (wchar_t *) L"shift-f12";
520             break;
521         }
522     }
523 
524     if (ptr == NULL && (event->modifiers() & Qt::ControlModifier)) {
525         switch (event->key()) {
526         case Qt::Key_Up:
527             ptr = (wchar_t *) L"ctrl-cursor-up";
528             break;
529         case Qt::Key_Down:
530             ptr = (wchar_t *) L"ctrl-cursor-down";
531             break;
532         case Qt::Key_Left:
533             ptr = (wchar_t *) L"ctrl-cursor-left";
534             break;
535         case Qt::Key_Right:
536             ptr = (wchar_t *) L"ctrl-cursor-right";
537             break;
538         case Qt::Key_PageUp:
539             ptr = (wchar_t *) L"ctrl-page-up";
540             break;
541         case Qt::Key_PageDown:
542             ptr = (wchar_t *) L"ctrl-page-down";
543             break;
544         case Qt::Key_Home:
545             ptr = (wchar_t *) L"ctrl-home";
546             break;
547         case Qt::Key_End:
548             ptr = (wchar_t *) L"ctrl-end";
549             break;
550         case Qt::Key_Space:
551             ptr = (wchar_t *) L"ctrl-space";
552             break;
553         case Qt::Key_F1:
554             ptr = (wchar_t *) L"ctrl-f1";
555             break;
556         case Qt::Key_F2:
557             ptr = (wchar_t *) L"ctrl-f2";
558             break;
559         case Qt::Key_F3:
560             ptr = (wchar_t *) L"ctrl-f3";
561             break;
562         case Qt::Key_F4:
563             ptr = (wchar_t *) L"ctrl-f4";
564             break;
565         case Qt::Key_F5:
566             ptr = (wchar_t *) L"ctrl-f5";
567             break;
568         case Qt::Key_F6:
569             ptr = (wchar_t *) L"ctrl-f6";
570             break;
571         case Qt::Key_F7:
572             ptr = (wchar_t *) L"ctrl-f7";
573             break;
574         case Qt::Key_F8:
575             ptr = (wchar_t *) L"ctrl-f8";
576             break;
577         case Qt::Key_F9:
578             ptr = (wchar_t *) L"ctrl-f9";
579             break;
580         case Qt::Key_F10:
581             ptr = (wchar_t *) L"ctrl-f10";
582             break;
583         case Qt::Key_F11:
584             ptr = (wchar_t *) L"ctrl-f11";
585             break;
586         case Qt::Key_F12:
587             ptr = (wchar_t *) L"ctrl-f12";
588             break;
589         case 'A':
590             ptr = (wchar_t *) L"ctrl-a";
591             break;
592         case 'B':
593             ptr = (wchar_t *) L"ctrl-b";
594             break;
595         case 'C':
596             ptr = (wchar_t *) L"ctrl-c";
597             break;
598         case 'D':
599             ptr = (wchar_t *) L"ctrl-d";
600             break;
601         case 'E':
602             ptr = (wchar_t *) L"ctrl-e";
603             break;
604         case 'F':
605             ptr = (wchar_t *) L"ctrl-f";
606             break;
607         case 'G':
608             ptr = (wchar_t *) L"ctrl-g";
609             break;
610         case 'H':
611             ptr = (wchar_t *) L"ctrl-h";
612             break;
613         case 'I':
614             ptr = (wchar_t *) L"ctrl-i";
615             break;
616         case 'J':
617             ptr = (wchar_t *) L"ctrl-j";
618             break;
619         case 'K':
620             ptr = (wchar_t *) L"ctrl-k";
621             break;
622         case 'L':
623             ptr = (wchar_t *) L"ctrl-l";
624             break;
625         case 'M':
626             ptr = (wchar_t *) L"ctrl-m";
627             break;
628         case 'N':
629             ptr = (wchar_t *) L"ctrl-n";
630             break;
631         case 'O':
632             ptr = (wchar_t *) L"ctrl-o";
633             break;
634         case 'P':
635             ptr = (wchar_t *) L"ctrl-p";
636             break;
637         case 'Q':
638             ptr = (wchar_t *) L"ctrl-q";
639             break;
640         case 'R':
641             ptr = (wchar_t *) L"ctrl-r";
642             break;
643         case 'S':
644             ptr = (wchar_t *) L"ctrl-s";
645             break;
646         case 'T':
647             ptr = (wchar_t *) L"ctrl-t";
648             break;
649         case 'U':
650             ptr = (wchar_t *) L"ctrl-u";
651             break;
652         case 'V':
653             ptr = (wchar_t *) L"ctrl-v";
654             break;
655         case 'W':
656             ptr = (wchar_t *) L"ctrl-w";
657             break;
658         case 'X':
659             ptr = (wchar_t *) L"ctrl-x";
660             break;
661         case 'Y':
662             ptr = (wchar_t *) L"ctrl-y";
663             break;
664         case 'Z':
665             ptr = (wchar_t *) L"ctrl-z";
666             break;
667         case Qt::Key_Return:
668         case Qt::Key_Enter:
669             ptr = (wchar_t *) L"ctrl-enter";
670             break;
671 
672         default:
673             break;
674         }
675     }
676     else
677     if (ptr == NULL && (event->modifiers() & Qt::AltModifier)) {
678         switch (event->key()) {
679         case Qt::Key_Up:
680             ptr = (wchar_t *) L"alt-cursor-up";
681             break;
682         case Qt::Key_Down:
683             ptr = (wchar_t *) L"alt-cursor-down";
684             break;
685         case Qt::Key_Left:
686             ptr = (wchar_t *) L"alt-cursor-left";
687             break;
688         case Qt::Key_Right:
689             ptr = (wchar_t *) L"alt-cursor-right";
690             break;
691         case Qt::Key_PageUp:
692             ptr = (wchar_t *) L"alt-page-up";
693             break;
694         case Qt::Key_PageDown:
695             ptr = (wchar_t *) L"alt-page-down";
696             break;
697         case Qt::Key_Home:
698             ptr = (wchar_t *) L"alt-home";
699             break;
700         case Qt::Key_End:
701             ptr = (wchar_t *) L"alt-end";
702             break;
703         case Qt::Key_Space:
704             ptr = (wchar_t *) L"alt-space";
705             break;
706         case Qt::Key_F1:
707             ptr = (wchar_t *) L"alt-f1";
708             break;
709         case Qt::Key_F2:
710             ptr = (wchar_t *) L"alt-f2";
711             break;
712         case Qt::Key_F3:
713             ptr = (wchar_t *) L"alt-f3";
714             break;
715         case Qt::Key_F4:
716             ptr = (wchar_t *) L"alt-f4";
717             break;
718         case Qt::Key_F5:
719             ptr = (wchar_t *) L"alt-f5";
720             break;
721         case Qt::Key_F6:
722             ptr = (wchar_t *) L"alt-f6";
723             break;
724         case Qt::Key_F7:
725             ptr = (wchar_t *) L"alt-f7";
726             break;
727         case Qt::Key_F8:
728             ptr = (wchar_t *) L"alt-f8";
729             break;
730         case Qt::Key_F9:
731             ptr = (wchar_t *) L"alt-f9";
732             break;
733         case Qt::Key_F10:
734             ptr = (wchar_t *) L"alt-f10";
735             break;
736         case Qt::Key_F11:
737             ptr = (wchar_t *) L"alt-f11";
738             break;
739         case Qt::Key_F12:
740             ptr = (wchar_t *) L"alt-f12";
741             break;
742         case 'A':
743             ptr = (wchar_t *) L"alt-a";
744             break;
745         case 'B':
746             ptr = (wchar_t *) L"alt-b";
747             break;
748         case 'C':
749             ptr = (wchar_t *) L"alt-c";
750             break;
751         case 'D':
752             ptr = (wchar_t *) L"alt-d";
753             break;
754         case 'E':
755             ptr = (wchar_t *) L"alt-e";
756             break;
757         case 'F':
758             ptr = (wchar_t *) L"alt-f";
759             break;
760         case 'G':
761             ptr = (wchar_t *) L"alt-g";
762             break;
763         case 'H':
764             ptr = (wchar_t *) L"alt-h";
765             break;
766         case 'I':
767             ptr = (wchar_t *) L"alt-i";
768             break;
769         case 'J':
770             ptr = (wchar_t *) L"alt-j";
771             break;
772         case 'K':
773             ptr = (wchar_t *) L"alt-k";
774             break;
775         case 'L':
776             ptr = (wchar_t *) L"alt-l";
777             break;
778         case 'M':
779             ptr = (wchar_t *) L"alt-m";
780             break;
781         case 'N':
782             ptr = (wchar_t *) L"alt-n";
783             break;
784         case 'O':
785             ptr = (wchar_t *) L"alt-o";
786             break;
787         case 'P':
788             ptr = (wchar_t *) L"alt-p";
789             break;
790         case 'Q':
791             ptr = (wchar_t *) L"alt-q";
792             break;
793         case 'R':
794             ptr = (wchar_t *) L"alt-r";
795             break;
796         case 'S':
797             ptr = (wchar_t *) L"alt-s";
798             break;
799         case 'T':
800             ptr = (wchar_t *) L"alt-t";
801             break;
802         case 'U':
803             ptr = (wchar_t *) L"alt-u";
804             break;
805         case 'V':
806             ptr = (wchar_t *) L"alt-v";
807             break;
808         case 'W':
809             ptr = (wchar_t *) L"alt-w";
810             break;
811         case 'X':
812             ptr = (wchar_t *) L"alt-x";
813             break;
814         case 'Y':
815             ptr = (wchar_t *) L"alt-y";
816             break;
817         case 'Z':
818             ptr = (wchar_t *) L"alt-z";
819             break;
820         case '-':
821             ptr = (wchar_t *) L"alt-minus";
822             break;
823         case Qt::Key_Return:
824         case Qt::Key_Enter:
825             ptr = (wchar_t *) L"alt-enter";
826             break;
827 
828         default:
829             break;
830         }
831     }
832     else
833     if (ptr == NULL) {
834         switch (event->key()) {
835         case Qt::Key_Up:
836             ptr = (wchar_t *) L"cursor-up";
837             break;
838         case Qt::Key_Down:
839             ptr = (wchar_t *) L"cursor-down";
840             break;
841         case Qt::Key_Left:
842             ptr = (wchar_t *) L"cursor-left";
843             break;
844         case Qt::Key_Right:
845             ptr = (wchar_t *) L"cursor-right";
846             break;
847         case Qt::Key_PageUp:
848             ptr = (wchar_t *) L"page-up";
849             break;
850         case Qt::Key_PageDown:
851             ptr = (wchar_t *) L"page-down";
852             break;
853         case Qt::Key_Home:
854             ptr = (wchar_t *) L"home";
855             break;
856         case Qt::Key_End:
857             ptr = (wchar_t *) L"end";
858             break;
859         case Qt::Key_Space:
860             ptr = (wchar_t *) L"space";
861             break;
862         case Qt::Key_F1:
863             ptr = (wchar_t *) L"f1";
864             break;
865         case Qt::Key_F2:
866             ptr = (wchar_t *) L"f2";
867             break;
868         case Qt::Key_F3:
869             ptr = (wchar_t *) L"f3";
870             break;
871         case Qt::Key_F4:
872             ptr = (wchar_t *) L"f4";
873             break;
874         case Qt::Key_F5:
875             ptr = (wchar_t *) L"f5";
876             break;
877         case Qt::Key_F6:
878             ptr = (wchar_t *) L"f6";
879             break;
880         case Qt::Key_F7:
881             ptr = (wchar_t *) L"f7";
882             break;
883         case Qt::Key_F8:
884             ptr = (wchar_t *) L"f8";
885             break;
886         case Qt::Key_F9:
887             ptr = (wchar_t *) L"f9";
888             break;
889         case Qt::Key_F10:
890             ptr = (wchar_t *) L"f10";
891             break;
892         case Qt::Key_F11:
893             ptr = (wchar_t *) L"f11";
894             break;
895         case Qt::Key_F12:
896             ptr = (wchar_t *) L"f12";
897             break;
898         case Qt::Key_Insert:
899             ptr = (wchar_t *) L"insert";
900             break;
901         case Qt::Key_Backspace:
902             ptr = (wchar_t *) L"backspace";
903             break;
904         case Qt::Key_Delete:
905             ptr = (wchar_t *) L"delete";
906             break;
907         case Qt::Key_Return:
908         case Qt::Key_Enter:
909             ptr = (wchar_t *) L"enter";
910             break;
911         case Qt::Key_Escape:
912             ptr = (wchar_t *) L"escape";
913             break;
914 
915         default:
916             break;
917         }
918     }
919 
920     if (ptr == NULL)
921         k = qstring_to_v(event->text());
922     else
923         k = MPDM_S(ptr);
924 
925     if (k != NULL)
926         mp_process_event(k);
927 
928     if (mp_keypress_throttle(1))
929         update();
930 }
931 
932 
mousePressEvent(QMouseEvent * event)933 void MPArea::mousePressEvent(QMouseEvent *event)
934 {
935     wchar_t *ptr = NULL;
936 
937     mouse_down = 1;
938 
939     QPoint pos = event->pos();
940 
941     mpdm_set_wcs(MP, MPDM_I(pos.x() / font_width),  L"mouse_x");
942     mpdm_set_wcs(MP, MPDM_I(pos.y() / font_height), L"mouse_y");
943 
944     switch (event->button()) {
945     case Qt::LeftButton:
946         ptr = (wchar_t *) L"mouse-left-button";
947         break;
948     case Qt::MidButton:
949         ptr = (wchar_t *) L"mouse-middle-button";
950         break;
951     case Qt::RightButton:
952         ptr = (wchar_t *) L"mouse-right-button";
953         break;
954     default:
955         break;
956     }
957 
958     if (ptr != NULL)
959         mp_process_event(MPDM_S(ptr));
960 
961     update();
962 }
963 
964 
mouseDoubleClickEvent(QMouseEvent * event)965 void MPArea::mouseDoubleClickEvent(QMouseEvent *event)
966 {
967     wchar_t *ptr = NULL;
968 
969     mouse_down = 1;
970 
971     QPoint pos = event->pos();
972 
973     mpdm_set_wcs(MP, MPDM_I(pos.x() / font_width),  L"mouse_x");
974     mpdm_set_wcs(MP, MPDM_I(pos.y() / font_height), L"mouse_y");
975 
976     switch (event->button()) {
977     case Qt::LeftButton:
978         ptr = (wchar_t *) L"mouse-left-dblclick";
979     default:
980         break;
981     }
982 
983     if (ptr != NULL)
984         mp_process_event(MPDM_S(ptr));
985 
986     update();
987 }
988 
989 
mouseReleaseEvent(QMouseEvent * event)990 void MPArea::mouseReleaseEvent(QMouseEvent *event)
991 {
992     mouse_down = 0;
993 }
994 
995 
mouseMoveEvent(QMouseEvent * event)996 void MPArea::mouseMoveEvent(QMouseEvent *event)
997 {
998     if (mouse_down) {
999         int x, y;
1000 
1001         QPoint pos = event->pos();
1002 
1003         /* mouse dragging */
1004         x = pos.x() / font_width;
1005         y = pos.y() / font_height;
1006 
1007         mpdm_set_wcs(MP, MPDM_I(x), L"mouse_to_x");
1008         mpdm_set_wcs(MP, MPDM_I(y), L"mouse_to_y");
1009 
1010         mp_process_event(MPDM_S(L"mouse-drag"));
1011 
1012         update();
1013     }
1014 }
1015 
1016 
wheelEvent(QWheelEvent * event)1017 void MPArea::wheelEvent(QWheelEvent *event)
1018 {
1019     if (event->delta() > 0)
1020         mp_process_event(MPDM_S(L"mouse-wheel-up"));
1021     else
1022         mp_process_event(MPDM_S(L"mouse-wheel-down"));
1023 
1024     update();
1025 }
1026 
1027 
dragEnterEvent(QDragEnterEvent * event)1028 void MPArea::dragEnterEvent(QDragEnterEvent *event)
1029 {
1030     if (event->mimeData()->hasFormat("text/uri-list"))
1031         event->acceptProposedAction();
1032 }
1033 
1034 
dropEvent(QDropEvent * event)1035 void MPArea::dropEvent(QDropEvent *event)
1036 {
1037     int n;
1038     mpdm_t v = qstring_to_v(event->mimeData()->text());
1039     mpdm_t l = MPDM_A(0);
1040 
1041     /* split the list of files */
1042     v = mpdm_split_wcs(v, L"\n");
1043 
1044     for (n = 0; n < (int) mpdm_size(v); n++) {
1045         wchar_t *ptr;
1046         mpdm_t w = mpdm_get_i(v, n);
1047 
1048         /* strip file:///, if found */
1049         ptr = mpdm_string(w);
1050 
1051         if (wcsncmp(ptr, L"file://", 7) == 0)
1052             ptr += 7;
1053 
1054         if (*ptr != L'\0')
1055             mpdm_push(l, MPDM_S(ptr));
1056     }
1057 
1058     mpdm_set_wcs(MP, l, L"dropped_files");
1059 
1060     event->acceptProposedAction();
1061     mp_process_event(MPDM_S(L"dropped-files"));
1062 
1063     update();
1064 }
1065 
1066 
1067 /** MPArea slots **/
1068 
from_scrollbar(int value)1069 void MPArea::from_scrollbar(int value)
1070 {
1071     if (!ignore_scrollbar_signal) {
1072         mpdm_t v = mp_active();
1073 
1074         mp_set_y(v, value);
1075 
1076         /* set the vy to the same value */
1077         v = mpdm_get_wcs(v, L"txt");
1078         mpdm_set_wcs(v, MPDM_I(value), L"vy");
1079 
1080         update();
1081     }
1082 }
1083 
1084 
from_filetabs(int value)1085 void MPArea::from_filetabs(int value)
1086 {
1087     if (value >= 0) {
1088         /* sets the active one */
1089         mpdm_set_wcs(MP, MPDM_I(value), L"active_i");
1090         update();
1091     }
1092 }
1093 
1094 
from_menu(QAction * action)1095 void MPArea::from_menu(QAction * action)
1096 {
1097     mp_process_action(qaction_to_action[action]);
1098 
1099     update();
1100 }
1101 
1102 
from_timer(void)1103 void MPArea::from_timer(void)
1104 {
1105     mp_process_event(MPDM_S(L"idle"));
1106     update();
1107 }
1108 
1109 
1110 /** driver functions **/
1111 
qt4_drv_clip_to_sys(mpdm_t a,mpdm_t ctxt)1112 static mpdm_t qt4_drv_clip_to_sys(mpdm_t a, mpdm_t ctxt)
1113 {
1114     mpdm_t v;
1115 
1116     QClipboard *qc = QApplication::clipboard();
1117 
1118     /* gets the clipboard and joins */
1119     v = mpdm_get_wcs(MP, L"clipboard");
1120 
1121     if (mpdm_size(v) != 0) {
1122         v = mpdm_ref(mpdm_join_wcs(v, L"\n"));
1123         qc->setText(v_to_qstring(v));
1124         mpdm_unref(v);
1125     }
1126 
1127     return NULL;
1128 }
1129 
1130 
qt4_drv_sys_to_clip(mpdm_t a,mpdm_t ctxt)1131 static mpdm_t qt4_drv_sys_to_clip(mpdm_t a, mpdm_t ctxt)
1132 {
1133     QClipboard *qc = QApplication::clipboard();
1134     QString qs = qc->text();
1135 
1136     /* split and set as the clipboard */
1137     mpdm_set_wcs(MP, mpdm_split_wcs(qstring_to_v(qs), L"\n"), L"clipboard");
1138 
1139     return NULL;
1140 }
1141 
1142 
qt4_drv_shutdown(mpdm_t a,mpdm_t ctxt)1143 static mpdm_t qt4_drv_shutdown(mpdm_t a, mpdm_t ctxt)
1144 {
1145     mpdm_t v;
1146 
1147     if ((v = mpdm_get_wcs(MP, L"exit_message")) != NULL) {
1148         mpdm_write_wcs(stdout, mpdm_string(v));
1149         printf("\n");
1150     }
1151 
1152     return NULL;
1153 }
1154 
1155 
1156 #include "mpv_qk_common.moc"
1157