Fix crash in new on_close handler.
[mp-5.x.git] / mpv_qk_common.cpp
blob86a79f76165bc96004869041f70776f164ec64dd
1 /*
3 Minimum Profit - Programmer Text Editor
5 Code common to Qt4 and KDE4 drivers.
7 Copyright (C) 2009/2010 Angel Ortega <angel@triptico.com>
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 http://www.triptico.com
27 MPArea *area;
28 QScrollBar *scrollbar;
29 static int font_width = -1;
30 static int font_height = -1;
31 static int mouse_down = 0;
32 static int key_down = 0;
34 mpdm_t timer_func = NULL;
36 /** code **/
38 static void draw_status(void);
40 static mpdm_t qstring_to_str(QString s)
41 /* converts a QString to an MPDM string */
43 mpdm_t r = NULL;
45 if (s != NULL) {
46 int t = s.size();
47 wchar_t *wptr = (wchar_t *) malloc((t + 1) * sizeof(wchar_t));
49 r = MPDM_ENS(wptr, t);
51 s.toWCharArray(wptr);
52 wptr[t] = L'\0';
55 return r;
59 QString str_to_qstring(mpdm_t s)
60 /* converts an MPDM string to a QString */
62 QString r;
63 wchar_t *wptr;
65 mpdm_ref(s);
66 wptr = mpdm_string(s);
67 r = QString::fromWCharArray(wptr);
68 mpdm_unref(s);
70 return r;
74 #define MAX_COLORS 1000
75 QPen inks[MAX_COLORS];
76 QBrush papers[MAX_COLORS];
77 bool underlines[MAX_COLORS];
78 int normal_attr = 0;
80 static void build_colors(void)
81 /* builds the colors */
83 mpdm_t colors;
84 mpdm_t l;
85 mpdm_t c;
86 int n, s;
88 /* gets the color definitions and attribute names */
89 colors = mpdm_hget_s(mp, L"colors");
90 l = mpdm_ref(mpdm_keys(colors));
91 s = mpdm_size(l);
93 /* loop the colors */
94 for (n = 0; n < s && (c = mpdm_aget(l, n)) != NULL; n++) {
95 int rgbi, rgbp;
96 mpdm_t d = mpdm_hget(colors, c);
97 mpdm_t v = mpdm_hget_s(d, L"gui");
99 /* store the 'normal' attribute */
100 if (wcscmp(mpdm_string(c), L"normal") == 0)
101 normal_attr = n;
103 /* store the attr */
104 mpdm_hset_s(d, L"attr", MPDM_I(n));
106 rgbi = mpdm_ival(mpdm_aget(v, 0));
107 rgbp = mpdm_ival(mpdm_aget(v, 1));
109 /* flags */
110 v = mpdm_hget_s(d, L"flags");
112 if (mpdm_seek_s(v, L"reverse", 1) != -1) {
113 int t = rgbi;
114 rgbi = rgbp;
115 rgbp = t;
118 underlines[n] =
119 mpdm_seek_s(v, L"underline", 1) != -1 ? true : false;
121 inks[n] = QPen(QColor::fromRgbF((float) ((rgbi & 0x00ff0000) >> 16)
122 / 256.0,
123 (float) ((rgbi & 0x0000ff00) >> 8)
124 / 256.0,
125 (float) ((rgbi & 0x000000ff)) /
126 256.0, 1));
128 papers[n] = QBrush(QColor::fromRgbF((float)
129 ((rgbp & 0x00ff0000) >> 16) /
130 256.0,
131 (float) ((rgbp & 0x0000ff00) >>
132 8) / 256.0,
133 (float) ((rgbp & 0x000000ff)) /
134 256.0, 1));
137 mpdm_unref(l);
141 static QFont build_font(int rebuild)
142 /* (re)builds the font */
144 static QFont font;
146 if (rebuild) {
147 mpdm_t c;
148 char *font_face = (char *) "Mono";
149 int font_size = 12;
150 mpdm_t w = NULL;
152 if ((c = mpdm_hget_s(mp, L"config")) != NULL) {
153 mpdm_t v;
155 if ((v = mpdm_hget_s(c, L"font_size")) != NULL)
156 font_size = mpdm_ival(v);
157 else
158 mpdm_hset_s(c, L"font_size", MPDM_I(font_size));
160 if ((v = mpdm_hget_s(c, L"font_face")) != NULL) {
161 w = mpdm_ref(MPDM_2MBS((wchar_t *) v->data));
162 font_face = (char *) w->data;
164 else
165 mpdm_hset_s(c, L"font_face", MPDM_MBS(font_face));
168 font = QFont(QString(font_face), font_size);
169 mpdm_unref(w);
172 return font;
176 static void build_menu(void)
177 /* builds the menu */
179 int n;
180 mpdm_t m;
182 /* gets the current menu */
183 if ((m = mpdm_hget_s(mp, L"menu")) == NULL)
184 return;
186 menubar->clear();
188 for (n = 0; n < mpdm_size(m); n++) {
189 mpdm_t mi;
190 mpdm_t v;
191 int i;
193 /* get the label */
194 mi = mpdm_aget(m, n);
195 v = mpdm_aget(mi, 0);
197 MENU_CLASS *menu = new MENU_CLASS(str_to_qstring(mpdm_gettext(v)));
199 /* get the items */
200 v = mpdm_aget(mi, 1);
202 for (i = 0; i < mpdm_size(v); i++) {
203 wchar_t *wptr;
204 mpdm_t w = mpdm_aget(v, i);
206 wptr = mpdm_string(w);
208 if (*wptr == L'-')
209 menu->addSeparator();
210 else
211 menu->addAction(str_to_qstring(mp_menu_label(w)));
214 menubar->addMenu(menu);
217 menubar->show();
221 static int ignore_scrollbar_signal = 0;
223 static void draw_scrollbar(void)
225 static int ol = -1;
226 static int ovy = -1;
227 static int oty = -1;
228 mpdm_t txt = mpdm_hget_s(mp_active(), L"txt");
229 mpdm_t window = mpdm_hget_s(mp, L"window");
230 int vy = mpdm_ival(mpdm_hget_s(txt, L"vy"));
231 int ty = mpdm_ival(mpdm_hget_s(window, L"ty"));
232 int l = mpdm_size(mpdm_hget_s(txt, L"lines")) - ty;
234 if (ol != l || ovy != vy || oty != ty) {
236 ignore_scrollbar_signal = 1;
238 scrollbar->setMinimum(0);
239 scrollbar->setMaximum(ol = l);
240 scrollbar->setValue(ovy = vy);
241 scrollbar->setPageStep(oty = ty);
243 ignore_scrollbar_signal = 0;
248 static void draw_filetabs(void)
250 static mpdm_t last = NULL;
251 mpdm_t names;
252 int n, i;
254 names = mpdm_ref(mp_get_doc_names());
256 /* get mp.active_i now, because it can be changed
257 from the signal handler */
258 i = mpdm_ival(mpdm_hget_s(mp, L"active_i"));
260 /* is the list different from the previous one? */
261 if (mpdm_cmp(names, last) != 0) {
263 while (file_tabs->count())
264 file_tabs->removeTab(0);
266 /* create the new ones */
267 for (n = 0; n < mpdm_size(names); n++)
268 file_tabs->addTab(str_to_qstring(mpdm_aget(names, n)));
270 /* store for the next time */
271 mpdm_unref(last);
272 last = mpdm_ref(names);
275 mpdm_unref(names);
277 /* set the active one */
278 file_tabs->setCurrentIndex(i);
282 /** MPArea methods **/
284 MPArea::MPArea(QWidget * parent):QWidget(parent)
286 setAttribute(Qt::WA_InputMethodEnabled, true);
288 setAcceptDrops(true);
290 timer = new QTimer();
291 connect(timer, SIGNAL(timeout()), this, SLOT(from_timer()));
295 bool MPArea::event(QEvent * event)
297 /* special tab processing */
298 if (event->type() == QEvent::KeyPress) {
299 QKeyEvent *ke = (QKeyEvent *) event;
301 if (ke->key() == Qt::Key_Tab) {
302 mp_process_event(MPDM_LS(L"tab"));
303 area->update();
304 return true;
306 else
307 if (ke->key() == Qt::Key_Backtab) {
308 mp_process_event(MPDM_LS(L"shift-tab"));
309 area->update();
310 return true;
314 /* keep normal processing */
315 return QWidget::event(event);
318 void MPArea::paintEvent(QPaintEvent *)
320 mpdm_t w;
321 int n, m, y;
322 QFont font;
323 bool underline = false;
325 QPainter painter(this);
327 font = build_font(0);
328 font.setUnderline(false);
329 painter.setFont(font);
331 font_width = painter.fontMetrics().width("M");
332 font_height = painter.fontMetrics().height();
334 /* calculate window size */
335 w = mpdm_hget_s(mp, L"window");
336 mpdm_hset_s(w, L"tx", MPDM_I(this->width() / font_width));
337 mpdm_hset_s(w, L"ty", MPDM_I(this->height() / font_height));
339 w = mp_draw(mp_active(), 0);
340 y = painter.fontMetrics().ascent() + 1;
342 painter.setBackgroundMode(Qt::OpaqueMode);
344 painter.setBrush(papers[normal_attr]);
345 painter.drawRect(0, 0, this->width(), this->height());
347 mpdm_ref(w);
349 for (n = 0; n < mpdm_size(w); n++) {
350 mpdm_t l = mpdm_aget(w, n);
351 int x = 0;
353 if (l == NULL)
354 continue;
356 for (m = 0; m < mpdm_size(l); m++) {
357 int attr;
358 mpdm_t s;
360 /* get the attribute and the string */
361 attr = mpdm_ival(mpdm_aget(l, m++));
362 s = mpdm_aget(l, m);
364 painter.setPen(inks[attr]);
365 painter.setBackground(papers[attr]);
367 QString qs = str_to_qstring(s);
369 if (underline != underlines[attr]) {
370 underline = underlines[attr];
371 font.setUnderline(underline);
372 painter.setFont(font);
375 painter.drawText(x, y, qs);
377 x += painter.fontMetrics().width(qs);
380 y += font_height;
383 mpdm_unref(w);
385 draw_filetabs();
386 draw_scrollbar();
387 draw_status();
389 area->setFocus(Qt::OtherFocusReason);
393 void MPArea::inputMethodEvent(QInputMethodEvent * event)
395 QString s = event->commitString();
397 mp_process_event(qstring_to_str(s));
398 area->update();
402 void MPArea::keyReleaseEvent(QKeyEvent * event)
404 if (!event->isAutoRepeat()) {
405 key_down = 0;
407 if (mp_keypress_throttle(0))
408 area->update();
413 void MPArea::keyPressEvent(QKeyEvent * event)
415 mpdm_t k = NULL;
416 wchar_t *ptr = NULL;
418 key_down = 1;
420 /* set mp.shift_pressed */
421 if (event->modifiers() & Qt::ShiftModifier)
422 mpdm_hset_s(mp, L"shift_pressed", MPDM_I(1));
424 if (event->modifiers() & Qt::ControlModifier) {
425 switch (event->key()) {
426 case Qt::Key_Up:
427 ptr = (wchar_t *) L"ctrl-cursor-up";
428 break;
429 case Qt::Key_Down:
430 ptr = (wchar_t *) L"ctrl-cursor-down";
431 break;
432 case Qt::Key_Left:
433 ptr = (wchar_t *) L"ctrl-cursor-left";
434 break;
435 case Qt::Key_Right:
436 ptr = (wchar_t *) L"ctrl-cursor-right";
437 break;
438 case Qt::Key_PageUp:
439 ptr = (wchar_t *) L"ctrl-page-up";
440 break;
441 case Qt::Key_PageDown:
442 ptr = (wchar_t *) L"ctrl-page-down";
443 break;
444 case Qt::Key_Home:
445 ptr = (wchar_t *) L"ctrl-home";
446 break;
447 case Qt::Key_End:
448 ptr = (wchar_t *) L"ctrl-end";
449 break;
450 case Qt::Key_Space:
451 ptr = (wchar_t *) L"ctrl-space";
452 break;
453 case Qt::Key_F1:
454 ptr = (wchar_t *) L"ctrl-f1";
455 break;
456 case Qt::Key_F2:
457 ptr = (wchar_t *) L"ctrl-f2";
458 break;
459 case Qt::Key_F3:
460 ptr = (wchar_t *) L"ctrl-f3";
461 break;
462 case Qt::Key_F4:
463 ptr = (wchar_t *) L"ctrl-f4";
464 break;
465 case Qt::Key_F5:
466 ptr = (wchar_t *) L"ctrl-f5";
467 break;
468 case Qt::Key_F6:
469 ptr = (wchar_t *) L"ctrl-f6";
470 break;
471 case Qt::Key_F7:
472 ptr = (wchar_t *) L"ctrl-f7";
473 break;
474 case Qt::Key_F8:
475 ptr = (wchar_t *) L"ctrl-f8";
476 break;
477 case Qt::Key_F9:
478 ptr = (wchar_t *) L"ctrl-f9";
479 break;
480 case Qt::Key_F10:
481 ptr = (wchar_t *) L"ctrl-f10";
482 break;
483 case Qt::Key_F11:
484 ptr = (wchar_t *) L"ctrl-f11";
485 break;
486 case Qt::Key_F12:
487 ptr = (wchar_t *) L"ctrl-f12";
488 break;
489 case 'A':
490 ptr = (wchar_t *) L"ctrl-a";
491 break;
492 case 'B':
493 ptr = (wchar_t *) L"ctrl-b";
494 break;
495 case 'C':
496 ptr = (wchar_t *) L"ctrl-c";
497 break;
498 case 'D':
499 ptr = (wchar_t *) L"ctrl-d";
500 break;
501 case 'E':
502 ptr = (wchar_t *) L"ctrl-e";
503 break;
504 case 'F':
505 ptr = (wchar_t *) L"ctrl-f";
506 break;
507 case 'G':
508 ptr = (wchar_t *) L"ctrl-g";
509 break;
510 case 'H':
511 ptr = (wchar_t *) L"ctrl-h";
512 break;
513 case 'I':
514 ptr = (wchar_t *) L"ctrl-i";
515 break;
516 case 'J':
517 ptr = (wchar_t *) L"ctrl-j";
518 break;
519 case 'K':
520 ptr = (wchar_t *) L"ctrl-k";
521 break;
522 case 'L':
523 ptr = (wchar_t *) L"ctrl-l";
524 break;
525 case 'M':
526 ptr = (wchar_t *) L"ctrl-m";
527 break;
528 case 'N':
529 ptr = (wchar_t *) L"ctrl-n";
530 break;
531 case 'O':
532 ptr = (wchar_t *) L"ctrl-o";
533 break;
534 case 'P':
535 ptr = (wchar_t *) L"ctrl-p";
536 break;
537 case 'Q':
538 ptr = (wchar_t *) L"ctrl-q";
539 break;
540 case 'R':
541 ptr = (wchar_t *) L"ctrl-r";
542 break;
543 case 'S':
544 ptr = (wchar_t *) L"ctrl-s";
545 break;
546 case 'T':
547 ptr = (wchar_t *) L"ctrl-t";
548 break;
549 case 'U':
550 ptr = (wchar_t *) L"ctrl-u";
551 break;
552 case 'V':
553 ptr = (wchar_t *) L"ctrl-v";
554 break;
555 case 'W':
556 ptr = (wchar_t *) L"ctrl-w";
557 break;
558 case 'X':
559 ptr = (wchar_t *) L"ctrl-x";
560 break;
561 case 'Y':
562 ptr = (wchar_t *) L"ctrl-y";
563 break;
564 case 'Z':
565 ptr = (wchar_t *) L"ctrl-z";
566 break;
567 case Qt::Key_Return:
568 case Qt::Key_Enter:
569 ptr = (wchar_t *) L"ctrl-enter";
570 break;
572 default:
573 break;
576 else
577 if (event->modifiers() & Qt::AltModifier) {
578 switch (event->key()) {
579 case Qt::Key_Up:
580 ptr = (wchar_t *) L"alt-cursor-up";
581 break;
582 case Qt::Key_Down:
583 ptr = (wchar_t *) L"alt-cursor-down";
584 break;
585 case Qt::Key_Left:
586 ptr = (wchar_t *) L"alt-cursor-left";
587 break;
588 case Qt::Key_Right:
589 ptr = (wchar_t *) L"alt-cursor-right";
590 break;
591 case Qt::Key_PageUp:
592 ptr = (wchar_t *) L"alt-page-up";
593 break;
594 case Qt::Key_PageDown:
595 ptr = (wchar_t *) L"alt-page-down";
596 break;
597 case Qt::Key_Home:
598 ptr = (wchar_t *) L"alt-home";
599 break;
600 case Qt::Key_End:
601 ptr = (wchar_t *) L"alt-end";
602 break;
603 case Qt::Key_Space:
604 ptr = (wchar_t *) L"alt-space";
605 break;
606 case Qt::Key_F1:
607 ptr = (wchar_t *) L"alt-f1";
608 break;
609 case Qt::Key_F2:
610 ptr = (wchar_t *) L"alt-f2";
611 break;
612 case Qt::Key_F3:
613 ptr = (wchar_t *) L"alt-f3";
614 break;
615 case Qt::Key_F4:
616 ptr = (wchar_t *) L"alt-f4";
617 break;
618 case Qt::Key_F5:
619 ptr = (wchar_t *) L"alt-f5";
620 break;
621 case Qt::Key_F6:
622 ptr = (wchar_t *) L"alt-f6";
623 break;
624 case Qt::Key_F7:
625 ptr = (wchar_t *) L"alt-f7";
626 break;
627 case Qt::Key_F8:
628 ptr = (wchar_t *) L"alt-f8";
629 break;
630 case Qt::Key_F9:
631 ptr = (wchar_t *) L"alt-f9";
632 break;
633 case Qt::Key_F10:
634 ptr = (wchar_t *) L"alt-f10";
635 break;
636 case Qt::Key_F11:
637 ptr = (wchar_t *) L"alt-f11";
638 break;
639 case Qt::Key_F12:
640 ptr = (wchar_t *) L"alt-f12";
641 break;
642 case 'A':
643 ptr = (wchar_t *) L"alt-a";
644 break;
645 case 'B':
646 ptr = (wchar_t *) L"alt-b";
647 break;
648 case 'C':
649 ptr = (wchar_t *) L"alt-c";
650 break;
651 case 'D':
652 ptr = (wchar_t *) L"alt-d";
653 break;
654 case 'E':
655 ptr = (wchar_t *) L"alt-e";
656 break;
657 case 'F':
658 ptr = (wchar_t *) L"alt-f";
659 break;
660 case 'G':
661 ptr = (wchar_t *) L"alt-g";
662 break;
663 case 'H':
664 ptr = (wchar_t *) L"alt-h";
665 break;
666 case 'I':
667 ptr = (wchar_t *) L"alt-i";
668 break;
669 case 'J':
670 ptr = (wchar_t *) L"alt-j";
671 break;
672 case 'K':
673 ptr = (wchar_t *) L"alt-k";
674 break;
675 case 'L':
676 ptr = (wchar_t *) L"alt-l";
677 break;
678 case 'M':
679 ptr = (wchar_t *) L"alt-m";
680 break;
681 case 'N':
682 ptr = (wchar_t *) L"alt-n";
683 break;
684 case 'O':
685 ptr = (wchar_t *) L"alt-o";
686 break;
687 case 'P':
688 ptr = (wchar_t *) L"alt-p";
689 break;
690 case 'Q':
691 ptr = (wchar_t *) L"alt-q";
692 break;
693 case 'R':
694 ptr = (wchar_t *) L"alt-r";
695 break;
696 case 'S':
697 ptr = (wchar_t *) L"alt-s";
698 break;
699 case 'T':
700 ptr = (wchar_t *) L"alt-t";
701 break;
702 case 'U':
703 ptr = (wchar_t *) L"alt-u";
704 break;
705 case 'V':
706 ptr = (wchar_t *) L"alt-v";
707 break;
708 case 'W':
709 ptr = (wchar_t *) L"alt-w";
710 break;
711 case 'X':
712 ptr = (wchar_t *) L"alt-x";
713 break;
714 case 'Y':
715 ptr = (wchar_t *) L"alt-y";
716 break;
717 case 'Z':
718 ptr = (wchar_t *) L"alt-z";
719 break;
720 case Qt::Key_Return:
721 case Qt::Key_Enter:
722 ptr = (wchar_t *) L"alt-enter";
723 break;
725 default:
726 break;
729 else {
730 switch (event->key()) {
731 case Qt::Key_Up:
732 ptr = (wchar_t *) L"cursor-up";
733 break;
734 case Qt::Key_Down:
735 ptr = (wchar_t *) L"cursor-down";
736 break;
737 case Qt::Key_Left:
738 ptr = (wchar_t *) L"cursor-left";
739 break;
740 case Qt::Key_Right:
741 ptr = (wchar_t *) L"cursor-right";
742 break;
743 case Qt::Key_PageUp:
744 ptr = (wchar_t *) L"page-up";
745 break;
746 case Qt::Key_PageDown:
747 ptr = (wchar_t *) L"page-down";
748 break;
749 case Qt::Key_Home:
750 ptr = (wchar_t *) L"home";
751 break;
752 case Qt::Key_End:
753 ptr = (wchar_t *) L"end";
754 break;
755 case Qt::Key_Space:
756 ptr = (wchar_t *) L"space";
757 break;
758 case Qt::Key_F1:
759 ptr = (wchar_t *) L"f1";
760 break;
761 case Qt::Key_F2:
762 ptr = (wchar_t *) L"f2";
763 break;
764 case Qt::Key_F3:
765 ptr = (wchar_t *) L"f3";
766 break;
767 case Qt::Key_F4:
768 ptr = (wchar_t *) L"f4";
769 break;
770 case Qt::Key_F5:
771 ptr = (wchar_t *) L"f5";
772 break;
773 case Qt::Key_F6:
774 ptr = (wchar_t *) L"f6";
775 break;
776 case Qt::Key_F7:
777 ptr = (wchar_t *) L"f7";
778 break;
779 case Qt::Key_F8:
780 ptr = (wchar_t *) L"f8";
781 break;
782 case Qt::Key_F9:
783 ptr = (wchar_t *) L"f9";
784 break;
785 case Qt::Key_F10:
786 ptr = (wchar_t *) L"f10";
787 break;
788 case Qt::Key_F11:
789 ptr = (wchar_t *) L"f11";
790 break;
791 case Qt::Key_F12:
792 ptr = (wchar_t *) L"f12";
793 break;
794 case Qt::Key_Insert:
795 ptr = (wchar_t *) L"insert";
796 break;
797 case Qt::Key_Backspace:
798 ptr = (wchar_t *) L"backspace";
799 break;
800 case Qt::Key_Delete:
801 ptr = (wchar_t *) L"delete";
802 break;
803 case Qt::Key_Return:
804 case Qt::Key_Enter:
805 ptr = (wchar_t *) L"enter";
806 break;
807 case Qt::Key_Escape:
808 ptr = (wchar_t *) L"escape";
809 break;
811 default:
812 break;
816 if (ptr == NULL)
817 k = qstring_to_str(event->text());
818 else
819 k = MPDM_S(ptr);
821 if (k != NULL)
822 mp_process_event(k);
824 if (mp_keypress_throttle(1))
825 area->update();
829 void MPArea::mousePressEvent(QMouseEvent * event)
831 wchar_t *ptr = NULL;
833 mouse_down = 1;
835 QPoint pos = event->pos();
837 mpdm_hset_s(mp, L"mouse_x", MPDM_I(pos.x() / font_width));
838 mpdm_hset_s(mp, L"mouse_y", MPDM_I(pos.y() / font_height));
840 switch (event->button()) {
841 case Qt::LeftButton:
842 ptr = (wchar_t *) L"mouse-left-button";
843 break;
844 case Qt::MidButton:
845 ptr = (wchar_t *) L"mouse-middle-button";
846 break;
847 case Qt::RightButton:
848 ptr = (wchar_t *) L"mouse-right-button";
849 break;
850 default:
851 break;
854 if (ptr != NULL)
855 mp_process_event(MPDM_S(ptr));
857 area->update();
861 void MPArea::mouseReleaseEvent(QMouseEvent * event)
863 mouse_down = 0;
867 void MPArea::mouseMoveEvent(QMouseEvent * event)
869 static int ox = 0;
870 static int oy = 0;
872 if (mouse_down) {
873 int x, y;
875 QPoint pos = event->pos();
877 /* mouse dragging */
878 x = pos.x() / font_width;
879 y = pos.y() / font_height;
881 if (ox != x && oy != y) {
882 mpdm_hset_s(mp, L"mouse_to_x", MPDM_I(x));
883 mpdm_hset_s(mp, L"mouse_to_y", MPDM_I(y));
885 mp_process_event(MPDM_LS(L"mouse-drag"));
887 area->update();
893 void MPArea::wheelEvent(QWheelEvent * event)
895 if (event->delta() > 0)
896 mp_process_event(MPDM_S(L"mouse-wheel-up"));
897 else
898 mp_process_event(MPDM_S(L"mouse-wheel-down"));
900 area->update();
904 void MPArea::dragEnterEvent(QDragEnterEvent * event)
906 if (event->mimeData()->hasFormat("text/uri-list"))
907 event->acceptProposedAction();
911 void MPArea::dropEvent(QDropEvent * event)
913 int n;
914 mpdm_t v = qstring_to_str(event->mimeData()->text());
915 mpdm_t l = MPDM_A(0);
917 mpdm_ref(l);
919 /* split the list of files */
920 v = mpdm_split_s(v, L"\n");
922 for (n = 0; n < mpdm_size(v); n++) {
923 wchar_t *ptr;
924 mpdm_t w = mpdm_aget(v, n);
926 /* strip file:///, if found */
927 ptr = mpdm_string(w);
929 if (wcsncmp(ptr, L"file://", 7) == 0)
930 ptr += 7;
932 if (*ptr != L'\0')
933 mpdm_push(l, MPDM_S(ptr));
936 mpdm_hset_s(mp, L"dropped_files", l);
938 event->acceptProposedAction();
939 mp_process_event(MPDM_LS(L"dropped-files"));
941 mpdm_unref(l);
943 area->update();
947 /** MPArea slots **/
949 void MPArea::from_scrollbar(int value)
951 if (!ignore_scrollbar_signal) {
952 mpdm_t v = mp_active();
954 mp_set_y(v, value);
956 /* set the vy to the same value */
957 v = mpdm_hget_s(v, L"txt");
958 mpdm_hset_s(v, L"vy", MPDM_I(value));
960 area->update();
965 void MPArea::from_filetabs(int value)
967 if (value >= 0) {
968 /* sets the active one */
969 mpdm_hset_s(mp, L"active_i", MPDM_I(value));
970 area->update();
975 void MPArea::from_menu(QAction * action)
977 mpdm_t label = qstring_to_str(action->text());
978 label = mpdm_sregex(label, MPDM_LS(L"/&/"), NULL, 0);
980 mpdm_t a = mpdm_hget_s(mp, L"actions_by_menu_label");
982 mp_process_action(mpdm_hget(a, label));
983 area->update();
987 void MPArea::from_timer(void)
989 mpdm_void(mpdm_exec(timer_func, NULL, NULL));
990 area->update();
994 /** driver functions **/
996 static mpdm_t qt4_drv_update_ui(mpdm_t a, mpdm_t ctxt)
998 build_font(1);
999 build_colors();
1000 build_menu();
1002 return NULL;
1006 static mpdm_t qt4_drv_busy(mpdm_t a, mpdm_t ctxt)
1008 int onoff = mpdm_ival(mpdm_aget(a, 0));
1010 window->setCursor(onoff ? Qt::WaitCursor : Qt::ArrowCursor);
1012 return NULL;
1016 static mpdm_t qt4_drv_main_loop(mpdm_t a, mpdm_t ctxt)
1018 app->exec();
1020 return NULL;
1024 static mpdm_t qt4_drv_shutdown(mpdm_t a, mpdm_t ctxt)
1026 mpdm_t v;
1028 if ((v = mpdm_hget_s(mp, L"exit_message")) != NULL) {
1029 mpdm_write_wcs(stdout, mpdm_string(v));
1030 printf("\n");
1033 return NULL;
1037 static mpdm_t qt4_drv_clip_to_sys(mpdm_t a, mpdm_t ctxt)
1039 mpdm_t v;
1041 QClipboard *qc = QApplication::clipboard();
1043 /* gets the clipboard and joins */
1044 v = mpdm_hget_s(mp, L"clipboard");
1046 if (mpdm_size(v) != 0) {
1047 v = mpdm_join_s(v, L"\n");
1048 qc->setText(str_to_qstring(v), QClipboard::Selection);
1051 return NULL;
1055 static mpdm_t qt4_drv_sys_to_clip(mpdm_t a, mpdm_t ctxt)
1057 QClipboard *qc = QApplication::clipboard();
1058 QString qs = qc->text(QClipboard::Selection);
1060 /* split and set as the clipboard */
1061 mpdm_hset_s(mp, L"clipboard", mpdm_split_s(qstring_to_str(qs), L"\n"));
1062 mpdm_hset_s(mp, L"clipboard_vertical", MPDM_I(0));
1064 return NULL;
1068 static mpdm_t qt4_drv_timer(mpdm_t a, mpdm_t ctxt)
1070 int msecs = mpdm_ival(mpdm_aget(a, 0));
1071 mpdm_t func = mpdm_aget(a, 1);
1073 mpdm_ref(func);
1074 mpdm_unref(timer_func);
1075 timer_func = func;
1077 if (timer_func == NULL)
1078 area->timer->stop();
1079 else
1080 area->timer->start(msecs);
1082 return NULL;