The repeated word configuration interface is accepted as working (Closes: #1274).
[mp-5.x.git] / mpv_kde4.cpp
blob7394ac2f1d545d16346827c834b7dca64ec213ac
1 /*
3 Minimum Profit - Programmer Text Editor
5 KDE4 driver.
7 Copyright (C) 2008-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 /* override auto-generated definition in config.h */
28 extern "C" int kde4_drv_detect(int * argc, char *** argv);
30 #include "config.h"
32 #include <stdio.h>
33 #include <wchar.h>
34 #include <unistd.h>
35 #include "mpdm.h"
36 #include "mpsl.h"
37 #include "mp.h"
39 #include <QtGui/QKeyEvent>
40 #include <QtGui/QPainter>
41 #include <QtGui/QMenu>
43 #include <QtGui/QLabel>
44 #include <QtGui/QComboBox>
45 #include <QtGui/QLineEdit>
46 #include <QtGui/QCheckBox>
47 #include <QtGui/QListWidget>
48 #include <QtGui/QScrollBar>
49 #include <QtGui/QClipboard>
51 #include <KApplication>
52 #include <KAboutData>
53 #include <KCmdLineArgs>
55 #include <KMainWindow>
56 #include <KMenuBar>
57 #include <KStatusBar>
58 #include <KMenu>
59 #include <KTabBar>
61 #include <KVBox>
62 #include <KHBox>
64 #include <KDialog>
65 #include <KMessageBox>
66 #include <KFileDialog>
67 #include <KUrl>
69 #include "mp.xpm"
71 /** data **/
73 class MPWindow : public KMainWindow
75 public:
76 MPWindow(QWidget *parent = 0);
77 bool queryExit(void);
78 bool event(QEvent *event);
81 class MPArea : public QWidget
83 Q_OBJECT
85 public:
86 MPArea(QWidget *parent = 0);
87 void inputMethodEvent(QInputMethodEvent *event);
88 void keyPressEvent(QKeyEvent *event);
89 void keyReleaseEvent(QKeyEvent *event);
90 void mousePressEvent(QMouseEvent *event);
91 void mouseReleaseEvent(QMouseEvent *event);
92 void mouseMoveEvent(QMouseEvent *event);
93 void wheelEvent(QWheelEvent *event);
94 bool event(QEvent *event);
96 protected:
97 void paintEvent(QPaintEvent *event);
99 public slots:
100 void from_scrollbar(int);
101 void from_filetabs(int);
102 void from_menu(QAction *);
105 /* global data */
106 KApplication *app;
107 MPWindow *window;
108 MPArea *area;
109 KMenuBar *menubar;
110 KStatusBar *statusbar;
111 QScrollBar *scrollbar;
112 KTabBar *file_tabs;
114 static int font_width = -1;
115 static int font_height = -1;
116 static int mouse_down = 0;
117 static int key_down = 0;
119 /** code **/
121 static mpdm_t qstring_to_str(QString s)
122 /* converts a QString to an MPDM string */
124 mpdm_t r = NULL;
126 if (s != NULL) {
127 int t = s.size();
128 wchar_t *wptr = (wchar_t *)malloc((t + 1) * sizeof(wchar_t));
130 r = MPDM_ENS(wptr, t);
132 s.toWCharArray(wptr);
133 wptr[t] = L'\0';
136 return r;
140 QString str_to_qstring(mpdm_t s)
141 /* converts an MPDM string to a QString */
143 wchar_t *wptr = mpdm_string(s);
144 return QString::fromWCharArray(wptr);
148 #define MAX_COLORS 1000
149 QPen inks[MAX_COLORS];
150 QBrush papers[MAX_COLORS];
151 bool underlines[MAX_COLORS];
152 int normal_attr = 0;
154 static void build_colors(void)
155 /* builds the colors */
157 mpdm_t colors;
158 mpdm_t l;
159 mpdm_t c;
160 int n, s;
162 /* gets the color definitions and attribute names */
163 colors = mpdm_hget_s(mp, L"colors");
164 l = mpdm_keys(colors);
165 s = mpdm_size(l);
167 /* loop the colors */
168 for (n = 0; n < s && (c = mpdm_aget(l, n)) != NULL; n++) {
169 int rgbi, rgbp;
170 mpdm_t d = mpdm_hget(colors, c);
171 mpdm_t v = mpdm_hget_s(d, L"gui");
173 /* store the 'normal' attribute */
174 if (wcscmp(mpdm_string(c), L"normal") == 0)
175 normal_attr = n;
177 /* store the attr */
178 mpdm_hset_s(d, L"attr", MPDM_I(n));
180 rgbi = mpdm_ival(mpdm_aget(v, 0));
181 rgbp = mpdm_ival(mpdm_aget(v, 1));
183 /* flags */
184 v = mpdm_hget_s(d, L"flags");
186 if (mpdm_seek_s(v, L"reverse", 1) != -1) {
187 int t = rgbi;
188 rgbi = rgbp;
189 rgbp = t;
192 underlines[n] = mpdm_seek_s(v, L"underline", 1) != -1 ? true : false;
194 inks[n] = QPen(QColor::fromRgbF(
195 (float) ((rgbi & 0x00ff0000) >> 16) / 256.0,
196 (float) ((rgbi & 0x0000ff00) >> 8) / 256.0,
197 (float) ((rgbi & 0x000000ff)) / 256.0,
198 1));
200 papers[n] = QBrush(QColor::fromRgbF(
201 (float) ((rgbp & 0x00ff0000) >> 16) / 256.0,
202 (float) ((rgbp & 0x0000ff00) >> 8) / 256.0,
203 (float) ((rgbp & 0x000000ff)) / 256.0,
204 1));
209 static QFont build_font(int rebuild)
210 /* (re)builds the font */
212 static QFont font;
214 if (rebuild) {
215 mpdm_t c;
216 char * font_face = (char *)"Mono";
217 int font_size = 12;
219 if ((c = mpdm_hget_s(mp, L"config")) != NULL) {
220 mpdm_t v;
222 if ((v = mpdm_hget_s(c, L"font_size")) != NULL)
223 font_size = mpdm_ival(v);
224 else
225 mpdm_hset_s(c, L"font_size", MPDM_I(font_size));
227 if ((v = mpdm_hget_s(c, L"font_face")) != NULL) {
228 v = MPDM_2MBS((wchar_t *)v->data);
229 font_face = (char *)v->data;
231 else
232 mpdm_hset_s(c, L"font_face", MPDM_MBS(font_face));
235 font = QFont(QString(font_face), font_size);
238 return font;
242 static void build_menu(void)
243 /* builds the menu */
245 int n;
246 mpdm_t m;
248 /* gets the current menu */
249 if ((m = mpdm_hget_s(mp, L"menu")) == NULL)
250 return;
252 menubar->clear();
254 for (n = 0; n < mpdm_size(m); n++) {
255 mpdm_t mi;
256 mpdm_t v;
257 int i;
259 /* get the label */
260 mi = mpdm_aget(m, n);
261 v = mpdm_aget(mi, 0);
263 KMenu *menu = new KMenu(str_to_qstring(mpdm_gettext(v)));
265 /* get the items */
266 v = mpdm_aget(mi, 1);
268 for (i = 0; i < mpdm_size(v); i++) {
269 wchar_t *wptr;
270 mpdm_t w = mpdm_aget(v, i);
272 wptr = mpdm_string(w);
274 if (*wptr == L'-')
275 menu->addSeparator();
276 else
277 menu->addAction(str_to_qstring(
278 mp_menu_label(w)));
281 menubar->addMenu(menu);
284 menubar->show();
288 static int ignore_scrollbar_signal = 0;
290 static void draw_scrollbar(void)
292 static int ol = -1;
293 static int ovy = -1;
294 static int oty = -1;
295 mpdm_t txt = mpdm_hget_s(mp_active(), L"txt");
296 mpdm_t window = mpdm_hget_s(mp, L"window");
297 int vy = mpdm_ival(mpdm_hget_s(txt, L"vy"));
298 int ty = mpdm_ival(mpdm_hget_s(window, L"ty"));
299 int l = mpdm_size(mpdm_hget_s(txt, L"lines")) - ty;
301 if (ol != l || ovy != vy || oty != ty) {
303 ignore_scrollbar_signal = 1;
305 scrollbar->setMinimum(0);
306 scrollbar->setMaximum(ol = l);
307 scrollbar->setValue(ovy = vy);
308 scrollbar->setPageStep(oty = ty);
310 ignore_scrollbar_signal = 0;
315 static void draw_status(void)
317 statusbar->changeItem(str_to_qstring(mp_build_status_line()), 0);
320 static void draw_filetabs(void)
322 static mpdm_t last = NULL;
323 mpdm_t names;
324 int n, i;
326 names = mp_get_doc_names();
328 /* get mp.active_i now, because it can be changed
329 from the signal handler */
330 i = mpdm_ival(mpdm_hget_s(mp, L"active_i"));
332 /* is the list different from the previous one? */
333 if (mpdm_cmp(names, last) != 0) {
335 while (file_tabs->count())
336 file_tabs->removeTab(0);
338 /* create the new ones */
339 for (n = 0; n < mpdm_size(names); n++)
340 file_tabs->addTab(str_to_qstring(mpdm_aget(names, n)));
342 /* store for the next time */
343 mpdm_unref(last);
344 last = mpdm_ref(names);
347 /* set the active one */
348 file_tabs->setCurrentIndex(i);
352 /** MPArea methods **/
354 MPArea::MPArea(QWidget *parent) : QWidget(parent)
356 setAttribute(Qt::WA_InputMethodEnabled, true);
360 bool MPArea::event(QEvent *event)
362 /* special tab processing */
363 if (event->type() == QEvent::KeyPress) {
364 QKeyEvent *ke = (QKeyEvent *)event;
366 if (ke->key() == Qt::Key_Tab) {
367 mp_process_event(MPDM_LS(L"tab"));
368 area->update();
369 return true;
373 /* keep normal processing */
374 return QWidget::event(event);
377 void MPArea::paintEvent(QPaintEvent *)
379 mpdm_t w;
380 int n, m, y;
381 QFont font;
382 bool underline = false;
384 QPainter painter(this);
386 font = build_font(0);
387 font.setUnderline(false);
388 painter.setFont(font);
390 font_width = painter.fontMetrics().width("M");
391 font_height = painter.fontMetrics().height();
393 /* calculate window size */
394 w = mpdm_hget_s(mp, L"window");
395 mpdm_hset_s(w, L"tx", MPDM_I(this->width() / font_width));
396 mpdm_hset_s(w, L"ty", MPDM_I(this->height() / font_height));
398 w = mp_draw(mp_active(), 0);
399 y = painter.fontMetrics().ascent() + 1;
401 painter.setBackgroundMode(Qt::OpaqueMode);
403 painter.setBrush(papers[normal_attr]);
404 painter.drawRect(0, 0, this->width(), this->height());
406 for (n = 0; n < mpdm_size(w); n++) {
407 mpdm_t l = mpdm_aget(w, n);
408 int x = 0;
410 if (l == NULL)
411 continue;
413 for (m = 0; m < mpdm_size(l); m++) {
414 int attr;
415 mpdm_t s;
417 /* get the attribute and the string */
418 attr = mpdm_ival(mpdm_aget(l, m++));
419 s = mpdm_aget(l, m);
421 painter.setPen(inks[attr]);
422 painter.setBackground(papers[attr]);
424 QString qs = str_to_qstring(s);
426 if (underline != underlines[attr]) {
427 underline = underlines[attr];
428 font.setUnderline(underline);
429 painter.setFont(font);
432 painter.drawText(x, y, qs);
434 x += painter.fontMetrics().width(qs);
437 y += font_height;
440 draw_filetabs();
441 draw_scrollbar();
442 draw_status();
444 area->setFocus(Qt::OtherFocusReason);
448 void MPArea::inputMethodEvent(QInputMethodEvent *event)
450 QString s = event->commitString();
452 mp_process_event(qstring_to_str(s));
453 area->update();
457 void MPArea::keyReleaseEvent(QKeyEvent *event)
459 if (!event->isAutoRepeat()) {
460 key_down = 0;
462 if (mp_keypress_throttle(0))
463 area->update();
468 void MPArea::keyPressEvent(QKeyEvent *event)
470 mpdm_t k = NULL;
471 wchar_t *ptr = NULL;
473 key_down = 1;
475 /* set mp.shift_pressed */
476 if (event->modifiers() & Qt::ShiftModifier)
477 mpdm_hset_s(mp, L"shift_pressed", MPDM_I(1));
479 if (event->modifiers() & Qt::ControlModifier) {
480 switch (event->key()) {
481 case Qt::Key_Up: ptr = (wchar_t *) L"ctrl-cursor-up"; break;
482 case Qt::Key_Down: ptr = (wchar_t *) L"ctrl-cursor-down"; break;
483 case Qt::Key_Left: ptr = (wchar_t *) L"ctrl-cursor-left"; break;
484 case Qt::Key_Right: ptr = (wchar_t *) L"ctrl-cursor-right"; break;
485 case Qt::Key_PageUp: ptr = (wchar_t *) L"ctrl-page-up"; break;
486 case Qt::Key_PageDown: ptr = (wchar_t *) L"ctrl-page-down"; break;
487 case Qt::Key_Home: ptr = (wchar_t *) L"ctrl-home"; break;
488 case Qt::Key_End: ptr = (wchar_t *) L"ctrl-end"; break;
489 case Qt::Key_Space: ptr = (wchar_t *) L"ctrl-space"; break;
490 case Qt::Key_F1: ptr = (wchar_t *) L"ctrl-f1"; break;
491 case Qt::Key_F2: ptr = (wchar_t *) L"ctrl-f2"; break;
492 case Qt::Key_F3: ptr = (wchar_t *) L"ctrl-f3"; break;
493 case Qt::Key_F4: ptr = (wchar_t *) L"ctrl-f4"; break;
494 case Qt::Key_F5: ptr = (wchar_t *) L"ctrl-f5"; break;
495 case Qt::Key_F6: ptr = (wchar_t *) L"ctrl-f6"; break;
496 case Qt::Key_F7: ptr = (wchar_t *) L"ctrl-f7"; break;
497 case Qt::Key_F8: ptr = (wchar_t *) L"ctrl-f8"; break;
498 case Qt::Key_F9: ptr = (wchar_t *) L"ctrl-f9"; break;
499 case Qt::Key_F10: ptr = (wchar_t *) L"ctrl-f10"; break;
500 case Qt::Key_F11: ptr = (wchar_t *) L"ctrl-f11"; break;
501 case Qt::Key_F12: ptr = (wchar_t *) L"ctrl-f12"; break;
502 case 'A': ptr = (wchar_t *) L"ctrl-a"; break;
503 case 'B': ptr = (wchar_t *) L"ctrl-b"; break;
504 case 'C': ptr = (wchar_t *) L"ctrl-c"; break;
505 case 'D': ptr = (wchar_t *) L"ctrl-d"; break;
506 case 'E': ptr = (wchar_t *) L"ctrl-e"; break;
507 case 'F': ptr = (wchar_t *) L"ctrl-f"; break;
508 case 'G': ptr = (wchar_t *) L"ctrl-g"; break;
509 case 'H': ptr = (wchar_t *) L"ctrl-h"; break;
510 case 'I': ptr = (wchar_t *) L"ctrl-i"; break;
511 case 'J': ptr = (wchar_t *) L"ctrl-j"; break;
512 case 'K': ptr = (wchar_t *) L"ctrl-k"; break;
513 case 'L': ptr = (wchar_t *) L"ctrl-l"; break;
514 case 'M': ptr = (wchar_t *) L"ctrl-m"; break;
515 case 'N': ptr = (wchar_t *) L"ctrl-n"; break;
516 case 'O': ptr = (wchar_t *) L"ctrl-o"; break;
517 case 'P': ptr = (wchar_t *) L"ctrl-p"; break;
518 case 'Q': ptr = (wchar_t *) L"ctrl-q"; break;
519 case 'R': ptr = (wchar_t *) L"ctrl-r"; break;
520 case 'S': ptr = (wchar_t *) L"ctrl-s"; break;
521 case 'T': ptr = (wchar_t *) L"ctrl-t"; break;
522 case 'U': ptr = (wchar_t *) L"ctrl-u"; break;
523 case 'V': ptr = (wchar_t *) L"ctrl-v"; break;
524 case 'W': ptr = (wchar_t *) L"ctrl-w"; break;
525 case 'X': ptr = (wchar_t *) L"ctrl-x"; break;
526 case 'Y': ptr = (wchar_t *) L"ctrl-y"; break;
527 case 'Z': ptr = (wchar_t *) L"ctrl-z"; break;
528 case Qt::Key_Return:
529 case Qt::Key_Enter: ptr = (wchar_t *) L"ctrl-enter"; break;
531 default:
532 break;
535 else {
536 switch (event->key()) {
537 case Qt::Key_Up: ptr = (wchar_t *) L"cursor-up"; break;
538 case Qt::Key_Down: ptr = (wchar_t *) L"cursor-down"; break;
539 case Qt::Key_Left: ptr = (wchar_t *) L"cursor-left"; break;
540 case Qt::Key_Right: ptr = (wchar_t *) L"cursor-right"; break;
541 case Qt::Key_PageUp: ptr = (wchar_t *) L"page-up"; break;
542 case Qt::Key_PageDown: ptr = (wchar_t *) L"page-down"; break;
543 case Qt::Key_Home: ptr = (wchar_t *) L"home"; break;
544 case Qt::Key_End: ptr = (wchar_t *) L"end"; break;
545 case Qt::Key_Space: ptr = (wchar_t *) L"space"; break;
546 case Qt::Key_F1: ptr = (wchar_t *) L"f1"; break;
547 case Qt::Key_F2: ptr = (wchar_t *) L"f2"; break;
548 case Qt::Key_F3: ptr = (wchar_t *) L"f3"; break;
549 case Qt::Key_F4: ptr = (wchar_t *) L"f4"; break;
550 case Qt::Key_F5: ptr = (wchar_t *) L"f5"; break;
551 case Qt::Key_F6: ptr = (wchar_t *) L"f6"; break;
552 case Qt::Key_F7: ptr = (wchar_t *) L"f7"; break;
553 case Qt::Key_F8: ptr = (wchar_t *) L"f8"; break;
554 case Qt::Key_F9: ptr = (wchar_t *) L"f9"; break;
555 case Qt::Key_F10: ptr = (wchar_t *) L"f10"; break;
556 case Qt::Key_F11: ptr = (wchar_t *) L"f11"; break;
557 case Qt::Key_F12: ptr = (wchar_t *) L"f12"; break;
558 case Qt::Key_Insert: ptr = (wchar_t *) L"insert"; break;
559 case Qt::Key_Backspace: ptr = (wchar_t *) L"backspace"; break;
560 case Qt::Key_Delete: ptr = (wchar_t *) L"delete"; break;
561 case Qt::Key_Return:
562 case Qt::Key_Enter: ptr = (wchar_t *) L"enter"; break;
563 case Qt::Key_Escape: ptr = (wchar_t *) L"escape"; break;
565 default:
566 break;
570 if (ptr == NULL)
571 k = qstring_to_str(event->text());
572 else
573 k = MPDM_S(ptr);
575 if (k != NULL)
576 mp_process_event(k);
578 if (mp_keypress_throttle(1))
579 area->update();
583 void MPArea::mousePressEvent(QMouseEvent *event)
585 wchar_t *ptr = NULL;
587 mouse_down = 1;
589 QPoint pos = event->pos();
591 mpdm_hset_s(mp, L"mouse_x", MPDM_I(pos.x() / font_width));
592 mpdm_hset_s(mp, L"mouse_y", MPDM_I(pos.y() / font_height));
594 switch (event->button()) {
595 case Qt::LeftButton: ptr = (wchar_t *)L"mouse-left-button"; break;
596 case Qt::MidButton: ptr = (wchar_t *)L"mouse-middle-button"; break;
597 case Qt::RightButton: ptr = (wchar_t *)L"mouse-right-button"; break;
598 default:
599 break;
602 if (ptr != NULL)
603 mp_process_event(MPDM_S(ptr));
605 area->update();
609 void MPArea::mouseReleaseEvent(QMouseEvent *event)
611 mouse_down = 0;
615 void MPArea::mouseMoveEvent(QMouseEvent *event)
617 static int ox = 0;
618 static int oy = 0;
620 if (mouse_down) {
621 int x, y;
623 QPoint pos = event->pos();
625 /* mouse dragging */
626 x = pos.x() / font_width;
627 y = pos.y() / font_height;
629 if (ox != x && oy != y) {
630 mpdm_hset_s(mp, L"mouse_to_x", MPDM_I(x));
631 mpdm_hset_s(mp, L"mouse_to_y", MPDM_I(y));
633 mp_process_event(MPDM_LS(L"mouse-drag"));
635 area->update();
641 void MPArea::wheelEvent(QWheelEvent *event)
643 if (event->delta() > 0)
644 mp_process_event(MPDM_S(L"mouse-wheel-up"));
645 else
646 mp_process_event(MPDM_S(L"mouse-wheel-down"));
648 area->update();
652 /** MPArea slots **/
654 void MPArea::from_scrollbar(int value)
656 if (!ignore_scrollbar_signal) {
657 mpdm_t v = mp_active();
659 mp_set_y(v, value);
661 /* set the vy to the same value */
662 v = mpdm_hget_s(v, L"txt");
663 mpdm_hset_s(v, L"vy", MPDM_I(value));
665 area->update();
670 void MPArea::from_filetabs(int value)
672 if (value >= 0) {
673 /* sets the active one */
674 mpdm_hset_s(mp, L"active_i", MPDM_I(value));
675 area->update();
680 void MPArea::from_menu(QAction *action)
682 mpdm_t label = qstring_to_str(action->text());
683 label = mpdm_sregex(MPDM_LS(L"/&/"), label, NULL, 0);
685 mpdm_t a = mpdm_hget_s(mp, L"actions_by_menu_label");
687 mp_process_action(mpdm_hget(a, label));
688 area->update();
692 /** MPWindow methods **/
694 MPWindow::MPWindow(QWidget *parent) : KMainWindow(parent)
696 menubar = this->menuBar();
697 build_menu();
699 statusbar = this->statusBar();
700 statusbar->insertItem("mp " VERSION, 0);
702 /* the full container */
703 KVBox *vb = new KVBox(this);
705 file_tabs = new KTabBar(vb);
706 file_tabs->setFocusPolicy(Qt::NoFocus);
708 KHBox *hb = new KHBox(vb);
710 /* main area */
711 area = new MPArea(hb);
712 scrollbar = new QScrollBar(hb);
713 scrollbar->setFocusPolicy(Qt::NoFocus);
715 setCentralWidget(vb);
717 connect(scrollbar, SIGNAL(valueChanged(int)),
718 area, SLOT(from_scrollbar(int)));
720 connect(file_tabs, SIGNAL(currentChanged(int)),
721 area, SLOT(from_filetabs(int)));
723 connect(menubar, SIGNAL(triggered(QAction *)),
724 area, SLOT(from_menu(QAction *)));
726 this->setWindowIcon(QIcon(QPixmap(mp_xpm)));
728 this->setAutoSaveSettings(QLatin1String("MinimumProfit"), true);
732 bool MPWindow::queryExit(void)
734 mp_process_event(MPDM_LS(L"close-window"));
736 this->saveAutoSaveSettings();
738 return mp_exit_requested ? true : false;
742 bool MPWindow::event(QEvent *event)
744 /* do the processing */
745 bool r = QWidget::event(event);
747 if (mp_exit_requested) {
748 this->saveAutoSaveSettings();
749 exit(0);
752 return r;
756 /** driver functions **/
758 static mpdm_t kde4_drv_update_ui(mpdm_t a)
760 build_font(1);
761 build_colors();
762 build_menu();
764 return NULL;
768 static mpdm_t kde4_drv_alert(mpdm_t a)
769 /* alert driver function */
771 /* 1# arg: prompt */
772 KMessageBox::information(0, str_to_qstring(mpdm_aget(a, 0)),
773 i18n("mp " VERSION));
775 return NULL;
778 static mpdm_t kde4_drv_confirm(mpdm_t a)
779 /* confirm driver function */
781 int r;
783 /* 1# arg: prompt */
784 r = KMessageBox::questionYesNoCancel(0,
785 str_to_qstring(mpdm_aget(a, 0)), i18n("mp" VERSION));
787 switch (r) {
788 case KMessageBox::Yes:
789 r = 1;
790 break;
792 case KMessageBox::No:
793 r = 2;
794 break;
796 case KMessageBox::Cancel:
797 r = 0;
798 break;
801 return MPDM_I(r);
805 static mpdm_t kde4_drv_openfile(mpdm_t a)
807 QString r;
808 char tmp[128];
810 getcwd(tmp, sizeof(tmp));
812 /* 1# arg: prompt */
813 r = KFileDialog::getOpenFileName(KUrl::fromPath(tmp), "*", 0,
814 str_to_qstring(mpdm_aget(a, 0)));
816 return qstring_to_str(r);
820 static mpdm_t kde4_drv_savefile(mpdm_t a)
822 QString r;
823 char tmp[128];
825 getcwd(tmp, sizeof(tmp));
827 /* 1# arg: prompt */
828 r = KFileDialog::getSaveFileName(KUrl::fromPath(tmp), "*", 0,
829 str_to_qstring(mpdm_aget(a, 0)));
831 return qstring_to_str(r);
835 static mpdm_t kde4_drv_form(mpdm_t a)
837 int n;
838 mpdm_t widget_list;
839 QWidget *qlist[100];
840 mpdm_t r;
842 KDialog *dialog = new KDialog(window);
844 dialog->setModal(true);
845 dialog->setButtons(KDialog::Ok | KDialog::Cancel);
847 widget_list = mpdm_aget(a, 0);
849 KVBox *vb = new KVBox(dialog);
850 dialog->setMainWidget(vb);
852 for (n = 0; n < mpdm_size(widget_list); n++) {
853 mpdm_t w = mpdm_aget(widget_list, n);
854 wchar_t *type;
855 mpdm_t t;
856 KHBox *hb = new KHBox(vb);
858 type = mpdm_string(mpdm_hget_s(w, L"type"));
860 if ((t = mpdm_hget_s(w, L"label")) != NULL) {
861 QLabel *ql = new QLabel(hb);
862 ql->setText(str_to_qstring(mpdm_gettext(t)));
865 t = mpdm_hget_s(w, L"value");
867 if (wcscmp(type, L"text") == 0) {
868 mpdm_t h;
869 QComboBox *ql = new QComboBox(hb);
871 ql->setEditable(true);
872 ql->setMinimumContentsLength(30);
873 ql->setMaxVisibleItems(8);
875 if (t != NULL)
876 ql->setEditText(str_to_qstring(t));
878 qlist[n] = ql;
880 if ((h = mpdm_hget_s(w, L"history")) != NULL) {
881 int i;
883 /* has history; fill it */
884 h = mp_get_history(h);
886 for (i = mpdm_size(h) - 1; i >= 0; i--)
887 ql->addItem(str_to_qstring(mpdm_aget(h, i)));
890 else
891 if (wcscmp(type, L"password") == 0) {
892 QLineEdit *ql = new QLineEdit(hb);
894 ql->setEchoMode(QLineEdit::Password);
896 qlist[n] = ql;
898 else
899 if (wcscmp(type, L"checkbox") == 0) {
900 QCheckBox *qc = new QCheckBox(hb);
902 if (mpdm_ival(t))
903 qc->setCheckState(Qt::Checked);
905 qlist[n] = qc;
907 else
908 if (wcscmp(type, L"list") == 0) {
909 int i;
910 QListWidget *ql = new QListWidget(hb);
911 ql->setMinimumWidth(480);
913 /* use a monospaced font */
914 ql->setFont(QFont(QString("Mono")));
916 mpdm_t l = mpdm_hget_s(w, L"list");
918 for (i = 0; i < mpdm_size(l); i++)
919 ql->addItem(str_to_qstring(mpdm_aget(l, i)));
921 ql->setCurrentRow(mpdm_ival(t));
923 qlist[n] = ql;
926 if (n == 0)
927 qlist[n]->setFocus(Qt::OtherFocusReason);
930 n = dialog->exec();
932 if (!n)
933 return NULL;
935 r = MPDM_A(mpdm_size(widget_list));
937 /* fill the return values */
938 for (n = 0; n < mpdm_size(widget_list); n++) {
939 mpdm_t w = mpdm_aget(widget_list, n);
940 mpdm_t v = NULL;
941 wchar_t *type;
943 type = mpdm_string(mpdm_hget_s(w, L"type"));
945 if (wcscmp(type, L"text") == 0) {
946 mpdm_t h;
947 QComboBox *ql = (QComboBox *)qlist[n];
949 v = qstring_to_str(ql->currentText());
951 /* if it has history, add to it */
952 if ((h = mpdm_hget_s(w, L"history")) != NULL &&
953 v != NULL && mpdm_cmp(v, MPDM_LS(L"")) != 0) {
954 h = mp_get_history(h);
956 if (mpdm_cmp(v, mpdm_aget(h, -1)) != 0)
957 mpdm_push(h, v);
960 else
961 if (wcscmp(type, L"password") == 0) {
962 QLineEdit *ql = (QLineEdit *)qlist[n];
964 v = qstring_to_str(ql->text());
966 else
967 if (wcscmp(type, L"checkbox") == 0) {
968 QCheckBox *qb = (QCheckBox *)qlist[n];
970 v = MPDM_I(qb->checkState() == Qt::Checked);
972 else
973 if (wcscmp(type, L"list") == 0) {
974 QListWidget *ql = (QListWidget *)qlist[n];
976 v = MPDM_I(ql->currentRow());
979 mpdm_aset(r, v, n);
982 return r;
986 static mpdm_t kde4_drv_busy(mpdm_t a)
988 int onoff = mpdm_ival(mpdm_aget(a, 0));
990 window->setCursor(onoff ? Qt::WaitCursor : Qt::ArrowCursor);
992 return NULL;
996 static mpdm_t kde4_drv_main_loop(mpdm_t a)
998 app->exec();
1000 return NULL;
1004 static mpdm_t kde4_drv_shutdown(mpdm_t a)
1006 mpdm_t v;
1008 if ((v = mpdm_hget_s(mp, L"exit_message")) != NULL) {
1009 mpdm_write_wcs(stdout, mpdm_string(v));
1010 printf("\n");
1013 return NULL;
1017 static mpdm_t kde4_drv_clip_to_sys(mpdm_t a)
1019 mpdm_t v;
1021 QClipboard *qc = QApplication::clipboard();
1023 /* gets the clipboard and joins */
1024 v = mpdm_hget_s(mp, L"clipboard");
1025 v = mpdm_join(MPDM_LS(L"\n"), v);
1027 qc->setText(str_to_qstring(v), QClipboard::Selection);
1029 return NULL;
1033 static mpdm_t kde4_drv_sys_to_clip(mpdm_t a)
1035 QClipboard *qc = QApplication::clipboard();
1036 QString qs = qc->text(QClipboard::Selection);
1038 /* split and set as the clipboard */
1039 mpdm_hset_s(mp, L"clipboard", mpdm_split(MPDM_LS(L"\n"),
1040 qstring_to_str(qs)));
1041 mpdm_hset_s(mp, L"clipboard_vertical", MPDM_I(0));
1043 return NULL;
1047 static void register_functions(void)
1049 mpdm_t drv;
1051 drv = mpdm_hget_s(mp, L"drv");
1052 mpdm_hset_s(drv, L"main_loop", MPDM_X(kde4_drv_main_loop));
1053 mpdm_hset_s(drv, L"shutdown", MPDM_X(kde4_drv_shutdown));
1055 mpdm_hset_s(drv, L"clip_to_sys", MPDM_X(kde4_drv_clip_to_sys));
1056 mpdm_hset_s(drv, L"sys_to_clip", MPDM_X(kde4_drv_sys_to_clip));
1057 mpdm_hset_s(drv, L"update_ui", MPDM_X(kde4_drv_update_ui));
1058 /* mpdm_hset_s(drv, L"timer", MPDM_X(kde4_drv_timer));*/
1059 mpdm_hset_s(drv, L"busy", MPDM_X(kde4_drv_busy));
1061 mpdm_hset_s(drv, L"alert", MPDM_X(kde4_drv_alert));
1062 mpdm_hset_s(drv, L"confirm", MPDM_X(kde4_drv_confirm));
1063 mpdm_hset_s(drv, L"openfile", MPDM_X(kde4_drv_openfile));
1064 mpdm_hset_s(drv, L"savefile", MPDM_X(kde4_drv_savefile));
1065 mpdm_hset_s(drv, L"form", MPDM_X(kde4_drv_form));
1069 static mpdm_t kde4_drv_startup(mpdm_t a)
1070 /* driver initialization */
1072 register_functions();
1074 build_font(1);
1075 build_colors();
1077 window = new MPWindow();
1078 window->show();
1080 return NULL;
1083 extern "C" Display *XOpenDisplay(char *);
1085 extern "C" int kde4_drv_detect(int * argc, char *** argv)
1087 mpdm_t drv;
1088 KCmdLineOptions opts;
1089 Display *x11_display;
1091 /* try connecting directly to the Xserver */
1092 if ((x11_display = XOpenDisplay((char *)NULL)) == NULL)
1093 return 0;
1095 KAboutData aboutData(
1096 "mp", 0,
1097 ki18n("Minimum Profit"), VERSION,
1098 ki18n("A programmer's text editor"),
1099 KAboutData::License_GPL,
1100 ki18n("Copyright (c) 1991-2008 Angel Ortega"),
1101 ki18n(""),
1102 "http://triptico.com",
1103 "angel@triptico.com"
1106 KCmdLineArgs::init(*argc, *argv, &aboutData);
1108 /* command line options should be inserted here (I don't like this) */
1109 opts.add("t {tag}", ki18n("Edits the file where tag is defined"));
1110 opts.add("e {mpsl_code}", ki18n("Executes MPSL code"));
1111 opts.add("f {mpsl_script}", ki18n("Executes MPSL script file"));
1112 opts.add("d {directory}", ki18n("Sets working directory"));
1113 opts.add(" +NNN", ki18n("Moves to line number NNN of last file"));
1114 opts.add("+[file(s)]", ki18n("Documents to open"));
1115 KCmdLineArgs::addCmdLineOptions(opts);
1117 /* this is where it crashes if no X server */
1118 app = new KApplication(x11_display);
1120 drv = mpdm_hget_s(mp, L"drv");
1121 mpdm_hset_s(drv, L"id", MPDM_LS(L"kde4"));
1122 mpdm_hset_s(drv, L"startup", MPDM_X(kde4_drv_startup));
1124 return 1;
1127 #include "mpv_kde4.moc"