Suppressed error in window initialisation.
[mp-5.x.git] / mpv_qk_common.cpp
blob864b8d0129dc1633deb8f82f49de883c5ca2cfb5
1 /*
3 Minimum Profit - Programmer Text Editor
5 Code common to Qt4 and KDE4 drivers.
7 Copyright (C) 2009 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 /** code **/
36 static void draw_status(void);
38 static mpdm_t qstring_to_str(QString s)
39 /* converts a QString to an MPDM string */
41 mpdm_t r = NULL;
43 if (s != NULL) {
44 int t = s.size();
45 wchar_t *wptr = (wchar_t *)malloc((t + 1) * sizeof(wchar_t));
47 r = MPDM_ENS(wptr, t);
49 s.toWCharArray(wptr);
50 wptr[t] = L'\0';
53 return r;
57 QString str_to_qstring(mpdm_t s)
58 /* converts an MPDM string to a QString */
60 wchar_t *wptr = mpdm_string(s);
61 return QString::fromWCharArray(wptr);
65 #define MAX_COLORS 1000
66 QPen inks[MAX_COLORS];
67 QBrush papers[MAX_COLORS];
68 bool underlines[MAX_COLORS];
69 int normal_attr = 0;
71 static void build_colors(void)
72 /* builds the colors */
74 mpdm_t colors;
75 mpdm_t l;
76 mpdm_t c;
77 int n, s;
79 /* gets the color definitions and attribute names */
80 colors = mpdm_hget_s(mp, L"colors");
81 l = mpdm_keys(colors);
82 s = mpdm_size(l);
84 /* loop the colors */
85 for (n = 0; n < s && (c = mpdm_aget(l, n)) != NULL; n++) {
86 int rgbi, rgbp;
87 mpdm_t d = mpdm_hget(colors, c);
88 mpdm_t v = mpdm_hget_s(d, L"gui");
90 /* store the 'normal' attribute */
91 if (wcscmp(mpdm_string(c), L"normal") == 0)
92 normal_attr = n;
94 /* store the attr */
95 mpdm_hset_s(d, L"attr", MPDM_I(n));
97 rgbi = mpdm_ival(mpdm_aget(v, 0));
98 rgbp = mpdm_ival(mpdm_aget(v, 1));
100 /* flags */
101 v = mpdm_hget_s(d, L"flags");
103 if (mpdm_seek_s(v, L"reverse", 1) != -1) {
104 int t = rgbi;
105 rgbi = rgbp;
106 rgbp = t;
109 underlines[n] = mpdm_seek_s(v, L"underline", 1) != -1 ? true : false;
111 inks[n] = QPen(QColor::fromRgbF(
112 (float) ((rgbi & 0x00ff0000) >> 16) / 256.0,
113 (float) ((rgbi & 0x0000ff00) >> 8) / 256.0,
114 (float) ((rgbi & 0x000000ff)) / 256.0,
115 1));
117 papers[n] = QBrush(QColor::fromRgbF(
118 (float) ((rgbp & 0x00ff0000) >> 16) / 256.0,
119 (float) ((rgbp & 0x0000ff00) >> 8) / 256.0,
120 (float) ((rgbp & 0x000000ff)) / 256.0,
121 1));
126 static QFont build_font(int rebuild)
127 /* (re)builds the font */
129 static QFont font;
131 if (rebuild) {
132 mpdm_t c;
133 char * font_face = (char *)"Mono";
134 int font_size = 12;
136 if ((c = mpdm_hget_s(mp, L"config")) != NULL) {
137 mpdm_t v;
139 if ((v = mpdm_hget_s(c, L"font_size")) != NULL)
140 font_size = mpdm_ival(v);
141 else
142 mpdm_hset_s(c, L"font_size", MPDM_I(font_size));
144 if ((v = mpdm_hget_s(c, L"font_face")) != NULL) {
145 v = MPDM_2MBS((wchar_t *)v->data);
146 font_face = (char *)v->data;
148 else
149 mpdm_hset_s(c, L"font_face", MPDM_MBS(font_face));
152 font = QFont(QString(font_face), font_size);
155 return font;
159 static void build_menu(void)
160 /* builds the menu */
162 int n;
163 mpdm_t m;
165 /* gets the current menu */
166 if ((m = mpdm_hget_s(mp, L"menu")) == NULL)
167 return;
169 menubar->clear();
171 for (n = 0; n < mpdm_size(m); n++) {
172 mpdm_t mi;
173 mpdm_t v;
174 int i;
176 /* get the label */
177 mi = mpdm_aget(m, n);
178 v = mpdm_aget(mi, 0);
180 MENU_CLASS *menu = new MENU_CLASS(str_to_qstring(mpdm_gettext(v)));
182 /* get the items */
183 v = mpdm_aget(mi, 1);
185 for (i = 0; i < mpdm_size(v); i++) {
186 wchar_t *wptr;
187 mpdm_t w = mpdm_aget(v, i);
189 wptr = mpdm_string(w);
191 if (*wptr == L'-')
192 menu->addSeparator();
193 else
194 menu->addAction(str_to_qstring(
195 mp_menu_label(w)));
198 menubar->addMenu(menu);
201 menubar->show();
205 static int ignore_scrollbar_signal = 0;
207 static void draw_scrollbar(void)
209 static int ol = -1;
210 static int ovy = -1;
211 static int oty = -1;
212 mpdm_t txt = mpdm_hget_s(mp_active(), L"txt");
213 mpdm_t window = mpdm_hget_s(mp, L"window");
214 int vy = mpdm_ival(mpdm_hget_s(txt, L"vy"));
215 int ty = mpdm_ival(mpdm_hget_s(window, L"ty"));
216 int l = mpdm_size(mpdm_hget_s(txt, L"lines")) - ty;
218 if (ol != l || ovy != vy || oty != ty) {
220 ignore_scrollbar_signal = 1;
222 scrollbar->setMinimum(0);
223 scrollbar->setMaximum(ol = l);
224 scrollbar->setValue(ovy = vy);
225 scrollbar->setPageStep(oty = ty);
227 ignore_scrollbar_signal = 0;
232 static void draw_filetabs(void)
234 static mpdm_t last = NULL;
235 mpdm_t names;
236 int n, i;
238 names = mp_get_doc_names();
240 /* get mp.active_i now, because it can be changed
241 from the signal handler */
242 i = mpdm_ival(mpdm_hget_s(mp, L"active_i"));
244 /* is the list different from the previous one? */
245 if (mpdm_cmp(names, last) != 0) {
247 while (file_tabs->count())
248 file_tabs->removeTab(0);
250 /* create the new ones */
251 for (n = 0; n < mpdm_size(names); n++)
252 file_tabs->addTab(str_to_qstring(mpdm_aget(names, n)));
254 /* store for the next time */
255 mpdm_unref(last);
256 last = mpdm_ref(names);
259 /* set the active one */
260 file_tabs->setCurrentIndex(i);
264 /** MPArea methods **/
266 MPArea::MPArea(QWidget *parent) : QWidget(parent)
268 setAttribute(Qt::WA_InputMethodEnabled, true);
270 setAcceptDrops(true);
274 bool MPArea::event(QEvent *event)
276 /* special tab processing */
277 if (event->type() == QEvent::KeyPress) {
278 QKeyEvent *ke = (QKeyEvent *)event;
280 if (ke->key() == Qt::Key_Tab) {
281 mp_process_event(MPDM_LS(L"tab"));
282 area->update();
283 return true;
287 /* keep normal processing */
288 return QWidget::event(event);
291 void MPArea::paintEvent(QPaintEvent *)
293 mpdm_t w;
294 int n, m, y;
295 QFont font;
296 bool underline = false;
298 QPainter painter(this);
300 font = build_font(0);
301 font.setUnderline(false);
302 painter.setFont(font);
304 font_width = painter.fontMetrics().width("M");
305 font_height = painter.fontMetrics().height();
307 /* calculate window size */
308 w = mpdm_hget_s(mp, L"window");
309 mpdm_hset_s(w, L"tx", MPDM_I(this->width() / font_width));
310 mpdm_hset_s(w, L"ty", MPDM_I(this->height() / font_height));
312 w = mp_draw(mp_active(), 0);
313 y = painter.fontMetrics().ascent() + 1;
315 painter.setBackgroundMode(Qt::OpaqueMode);
317 painter.setBrush(papers[normal_attr]);
318 painter.drawRect(0, 0, this->width(), this->height());
320 for (n = 0; n < mpdm_size(w); n++) {
321 mpdm_t l = mpdm_aget(w, n);
322 int x = 0;
324 if (l == NULL)
325 continue;
327 for (m = 0; m < mpdm_size(l); m++) {
328 int attr;
329 mpdm_t s;
331 /* get the attribute and the string */
332 attr = mpdm_ival(mpdm_aget(l, m++));
333 s = mpdm_aget(l, m);
335 painter.setPen(inks[attr]);
336 painter.setBackground(papers[attr]);
338 QString qs = str_to_qstring(s);
340 if (underline != underlines[attr]) {
341 underline = underlines[attr];
342 font.setUnderline(underline);
343 painter.setFont(font);
346 painter.drawText(x, y, qs);
348 x += painter.fontMetrics().width(qs);
351 y += font_height;
354 draw_filetabs();
355 draw_scrollbar();
356 draw_status();
358 area->setFocus(Qt::OtherFocusReason);
362 void MPArea::inputMethodEvent(QInputMethodEvent *event)
364 QString s = event->commitString();
366 mp_process_event(qstring_to_str(s));
367 area->update();
371 void MPArea::keyReleaseEvent(QKeyEvent *event)
373 if (!event->isAutoRepeat()) {
374 key_down = 0;
376 if (mp_keypress_throttle(0))
377 area->update();
382 void MPArea::keyPressEvent(QKeyEvent *event)
384 mpdm_t k = NULL;
385 wchar_t *ptr = NULL;
387 key_down = 1;
389 /* set mp.shift_pressed */
390 if (event->modifiers() & Qt::ShiftModifier)
391 mpdm_hset_s(mp, L"shift_pressed", MPDM_I(1));
393 if (event->modifiers() & Qt::ControlModifier) {
394 switch (event->key()) {
395 case Qt::Key_Up: ptr = (wchar_t *) L"ctrl-cursor-up"; break;
396 case Qt::Key_Down: ptr = (wchar_t *) L"ctrl-cursor-down"; break;
397 case Qt::Key_Left: ptr = (wchar_t *) L"ctrl-cursor-left"; break;
398 case Qt::Key_Right: ptr = (wchar_t *) L"ctrl-cursor-right"; break;
399 case Qt::Key_PageUp: ptr = (wchar_t *) L"ctrl-page-up"; break;
400 case Qt::Key_PageDown: ptr = (wchar_t *) L"ctrl-page-down"; break;
401 case Qt::Key_Home: ptr = (wchar_t *) L"ctrl-home"; break;
402 case Qt::Key_End: ptr = (wchar_t *) L"ctrl-end"; break;
403 case Qt::Key_Space: ptr = (wchar_t *) L"ctrl-space"; break;
404 case Qt::Key_F1: ptr = (wchar_t *) L"ctrl-f1"; break;
405 case Qt::Key_F2: ptr = (wchar_t *) L"ctrl-f2"; break;
406 case Qt::Key_F3: ptr = (wchar_t *) L"ctrl-f3"; break;
407 case Qt::Key_F4: ptr = (wchar_t *) L"ctrl-f4"; break;
408 case Qt::Key_F5: ptr = (wchar_t *) L"ctrl-f5"; break;
409 case Qt::Key_F6: ptr = (wchar_t *) L"ctrl-f6"; break;
410 case Qt::Key_F7: ptr = (wchar_t *) L"ctrl-f7"; break;
411 case Qt::Key_F8: ptr = (wchar_t *) L"ctrl-f8"; break;
412 case Qt::Key_F9: ptr = (wchar_t *) L"ctrl-f9"; break;
413 case Qt::Key_F10: ptr = (wchar_t *) L"ctrl-f10"; break;
414 case Qt::Key_F11: ptr = (wchar_t *) L"ctrl-f11"; break;
415 case Qt::Key_F12: ptr = (wchar_t *) L"ctrl-f12"; break;
416 case 'A': ptr = (wchar_t *) L"ctrl-a"; break;
417 case 'B': ptr = (wchar_t *) L"ctrl-b"; break;
418 case 'C': ptr = (wchar_t *) L"ctrl-c"; break;
419 case 'D': ptr = (wchar_t *) L"ctrl-d"; break;
420 case 'E': ptr = (wchar_t *) L"ctrl-e"; break;
421 case 'F': ptr = (wchar_t *) L"ctrl-f"; break;
422 case 'G': ptr = (wchar_t *) L"ctrl-g"; break;
423 case 'H': ptr = (wchar_t *) L"ctrl-h"; break;
424 case 'I': ptr = (wchar_t *) L"ctrl-i"; break;
425 case 'J': ptr = (wchar_t *) L"ctrl-j"; break;
426 case 'K': ptr = (wchar_t *) L"ctrl-k"; break;
427 case 'L': ptr = (wchar_t *) L"ctrl-l"; break;
428 case 'M': ptr = (wchar_t *) L"ctrl-m"; break;
429 case 'N': ptr = (wchar_t *) L"ctrl-n"; break;
430 case 'O': ptr = (wchar_t *) L"ctrl-o"; break;
431 case 'P': ptr = (wchar_t *) L"ctrl-p"; break;
432 case 'Q': ptr = (wchar_t *) L"ctrl-q"; break;
433 case 'R': ptr = (wchar_t *) L"ctrl-r"; break;
434 case 'S': ptr = (wchar_t *) L"ctrl-s"; break;
435 case 'T': ptr = (wchar_t *) L"ctrl-t"; break;
436 case 'U': ptr = (wchar_t *) L"ctrl-u"; break;
437 case 'V': ptr = (wchar_t *) L"ctrl-v"; break;
438 case 'W': ptr = (wchar_t *) L"ctrl-w"; break;
439 case 'X': ptr = (wchar_t *) L"ctrl-x"; break;
440 case 'Y': ptr = (wchar_t *) L"ctrl-y"; break;
441 case 'Z': ptr = (wchar_t *) L"ctrl-z"; break;
442 case Qt::Key_Return:
443 case Qt::Key_Enter: ptr = (wchar_t *) L"ctrl-enter"; break;
445 default:
446 break;
449 else {
450 switch (event->key()) {
451 case Qt::Key_Up: ptr = (wchar_t *) L"cursor-up"; break;
452 case Qt::Key_Down: ptr = (wchar_t *) L"cursor-down"; break;
453 case Qt::Key_Left: ptr = (wchar_t *) L"cursor-left"; break;
454 case Qt::Key_Right: ptr = (wchar_t *) L"cursor-right"; break;
455 case Qt::Key_PageUp: ptr = (wchar_t *) L"page-up"; break;
456 case Qt::Key_PageDown: ptr = (wchar_t *) L"page-down"; break;
457 case Qt::Key_Home: ptr = (wchar_t *) L"home"; break;
458 case Qt::Key_End: ptr = (wchar_t *) L"end"; break;
459 case Qt::Key_Space: ptr = (wchar_t *) L"space"; break;
460 case Qt::Key_F1: ptr = (wchar_t *) L"f1"; break;
461 case Qt::Key_F2: ptr = (wchar_t *) L"f2"; break;
462 case Qt::Key_F3: ptr = (wchar_t *) L"f3"; break;
463 case Qt::Key_F4: ptr = (wchar_t *) L"f4"; break;
464 case Qt::Key_F5: ptr = (wchar_t *) L"f5"; break;
465 case Qt::Key_F6: ptr = (wchar_t *) L"f6"; break;
466 case Qt::Key_F7: ptr = (wchar_t *) L"f7"; break;
467 case Qt::Key_F8: ptr = (wchar_t *) L"f8"; break;
468 case Qt::Key_F9: ptr = (wchar_t *) L"f9"; break;
469 case Qt::Key_F10: ptr = (wchar_t *) L"f10"; break;
470 case Qt::Key_F11: ptr = (wchar_t *) L"f11"; break;
471 case Qt::Key_F12: ptr = (wchar_t *) L"f12"; break;
472 case Qt::Key_Insert: ptr = (wchar_t *) L"insert"; break;
473 case Qt::Key_Backspace: ptr = (wchar_t *) L"backspace"; break;
474 case Qt::Key_Delete: ptr = (wchar_t *) L"delete"; break;
475 case Qt::Key_Return:
476 case Qt::Key_Enter: ptr = (wchar_t *) L"enter"; break;
477 case Qt::Key_Escape: ptr = (wchar_t *) L"escape"; break;
479 default:
480 break;
484 if (ptr == NULL)
485 k = qstring_to_str(event->text());
486 else
487 k = MPDM_S(ptr);
489 if (k != NULL)
490 mp_process_event(k);
492 if (mp_keypress_throttle(1))
493 area->update();
497 void MPArea::mousePressEvent(QMouseEvent *event)
499 wchar_t *ptr = NULL;
501 mouse_down = 1;
503 QPoint pos = event->pos();
505 mpdm_hset_s(mp, L"mouse_x", MPDM_I(pos.x() / font_width));
506 mpdm_hset_s(mp, L"mouse_y", MPDM_I(pos.y() / font_height));
508 switch (event->button()) {
509 case Qt::LeftButton: ptr = (wchar_t *)L"mouse-left-button"; break;
510 case Qt::MidButton: ptr = (wchar_t *)L"mouse-middle-button"; break;
511 case Qt::RightButton: ptr = (wchar_t *)L"mouse-right-button"; break;
512 default:
513 break;
516 if (ptr != NULL)
517 mp_process_event(MPDM_S(ptr));
519 area->update();
523 void MPArea::mouseReleaseEvent(QMouseEvent *event)
525 mouse_down = 0;
529 void MPArea::mouseMoveEvent(QMouseEvent *event)
531 static int ox = 0;
532 static int oy = 0;
534 if (mouse_down) {
535 int x, y;
537 QPoint pos = event->pos();
539 /* mouse dragging */
540 x = pos.x() / font_width;
541 y = pos.y() / font_height;
543 if (ox != x && oy != y) {
544 mpdm_hset_s(mp, L"mouse_to_x", MPDM_I(x));
545 mpdm_hset_s(mp, L"mouse_to_y", MPDM_I(y));
547 mp_process_event(MPDM_LS(L"mouse-drag"));
549 area->update();
555 void MPArea::wheelEvent(QWheelEvent *event)
557 if (event->delta() > 0)
558 mp_process_event(MPDM_S(L"mouse-wheel-up"));
559 else
560 mp_process_event(MPDM_S(L"mouse-wheel-down"));
562 area->update();
566 void MPArea::dragEnterEvent(QDragEnterEvent *event)
568 if (event->mimeData()->hasFormat("text/uri-list"))
569 event->acceptProposedAction();
573 void MPArea::dropEvent(QDropEvent *event)
575 int n;
576 mpdm_t v = qstring_to_str(event->mimeData()->text());
577 mpdm_t l = MPDM_A(0);
579 /* split the list of files */
580 v = mpdm_split(MPDM_LS(L"\n"), v);
582 for (n = 0; n < mpdm_size(v); n++) {
583 wchar_t *ptr;
584 mpdm_t w = mpdm_aget(v, n);
586 /* strip file:///, if found */
587 ptr = mpdm_string(w);
589 if (wcsncmp(ptr, L"file://", 7) == 0)
590 ptr += 7;
592 if (*ptr != L'\0')
593 mpdm_push(l, MPDM_S(ptr));
596 mpdm_hset_s(mp, L"dropped_files", l);
598 event->acceptProposedAction();
599 mp_process_event(MPDM_LS(L"dropped-files"));
601 area->update();
605 /** MPArea slots **/
607 void MPArea::from_scrollbar(int value)
609 if (!ignore_scrollbar_signal) {
610 mpdm_t v = mp_active();
612 mp_set_y(v, value);
614 /* set the vy to the same value */
615 v = mpdm_hget_s(v, L"txt");
616 mpdm_hset_s(v, L"vy", MPDM_I(value));
618 area->update();
623 void MPArea::from_filetabs(int value)
625 if (value >= 0) {
626 /* sets the active one */
627 mpdm_hset_s(mp, L"active_i", MPDM_I(value));
628 area->update();
633 void MPArea::from_menu(QAction *action)
635 mpdm_t label = qstring_to_str(action->text());
636 label = mpdm_sregex(MPDM_LS(L"/&/"), label, NULL, 0);
638 mpdm_t a = mpdm_hget_s(mp, L"actions_by_menu_label");
640 mp_process_action(mpdm_hget(a, label));
641 area->update();
645 /** driver functions **/
647 static mpdm_t qt4_drv_update_ui(mpdm_t a)
649 build_font(1);
650 build_colors();
651 build_menu();
653 return NULL;
657 static mpdm_t qt4_drv_busy(mpdm_t a)
659 int onoff = mpdm_ival(mpdm_aget(a, 0));
661 window->setCursor(onoff ? Qt::WaitCursor : Qt::ArrowCursor);
663 return NULL;
667 static mpdm_t qt4_drv_main_loop(mpdm_t a)
669 app->exec();
671 return NULL;
675 static mpdm_t qt4_drv_shutdown(mpdm_t a)
677 mpdm_t v;
679 if ((v = mpdm_hget_s(mp, L"exit_message")) != NULL) {
680 mpdm_write_wcs(stdout, mpdm_string(v));
681 printf("\n");
684 return NULL;
688 static mpdm_t qt4_drv_clip_to_sys(mpdm_t a)
690 mpdm_t v;
692 QClipboard *qc = QApplication::clipboard();
694 /* gets the clipboard and joins */
695 v = mpdm_hget_s(mp, L"clipboard");
697 if (mpdm_size(v) != 0) {
698 v = mpdm_join(MPDM_LS(L"\n"), v);
699 qc->setText(str_to_qstring(v), QClipboard::Selection);
702 return NULL;
706 static mpdm_t qt4_drv_sys_to_clip(mpdm_t a)
708 QClipboard *qc = QApplication::clipboard();
709 QString qs = qc->text(QClipboard::Selection);
711 /* split and set as the clipboard */
712 mpdm_hset_s(mp, L"clipboard", mpdm_split(MPDM_LS(L"\n"),
713 qstring_to_str(qs)));
714 mpdm_hset_s(mp, L"clipboard_vertical", MPDM_I(0));
716 return NULL;