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
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;
36 static void draw_status(void);
38 static mpdm_t
qstring_to_str(QString s
)
39 /* converts a QString to an MPDM string */
45 wchar_t *wptr
= (wchar_t *)malloc((t
+ 1) * sizeof(wchar_t));
47 r
= MPDM_ENS(wptr
, t
);
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
];
71 static void build_colors(void)
72 /* builds the colors */
79 /* gets the color definitions and attribute names */
80 colors
= mpdm_hget_s(mp
, L
"colors");
81 l
= mpdm_keys(colors
);
85 for (n
= 0; n
< s
&& (c
= mpdm_aget(l
, n
)) != NULL
; n
++) {
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)
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));
101 v
= mpdm_hget_s(d
, L
"flags");
103 if (mpdm_seek_s(v
, L
"reverse", 1) != -1) {
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,
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,
126 static QFont
build_font(int rebuild
)
127 /* (re)builds the font */
133 char * font_face
= (char *)"Mono";
136 if ((c
= mpdm_hget_s(mp
, L
"config")) != NULL
) {
139 if ((v
= mpdm_hget_s(c
, L
"font_size")) != NULL
)
140 font_size
= mpdm_ival(v
);
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
;
149 mpdm_hset_s(c
, L
"font_face", MPDM_MBS(font_face
));
152 font
= QFont(QString(font_face
), font_size
);
159 static void build_menu(void)
160 /* builds the menu */
165 /* gets the current menu */
166 if ((m
= mpdm_hget_s(mp
, L
"menu")) == NULL
)
171 for (n
= 0; n
< mpdm_size(m
); n
++) {
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
)));
183 v
= mpdm_aget(mi
, 1);
185 for (i
= 0; i
< mpdm_size(v
); i
++) {
187 mpdm_t w
= mpdm_aget(v
, i
);
189 wptr
= mpdm_string(w
);
192 menu
->addSeparator();
194 menu
->addAction(str_to_qstring(
198 menubar
->addMenu(menu
);
205 static int ignore_scrollbar_signal
= 0;
207 static void draw_scrollbar(void)
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
;
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 */
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"));
287 /* keep normal processing */
288 return QWidget::event(event
);
291 void MPArea::paintEvent(QPaintEvent
*)
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
);
327 for (m
= 0; m
< mpdm_size(l
); m
++) {
331 /* get the attribute and the string */
332 attr
= mpdm_ival(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
);
358 area
->setFocus(Qt::OtherFocusReason
);
362 void MPArea::inputMethodEvent(QInputMethodEvent
*event
)
364 QString s
= event
->commitString();
366 mp_process_event(qstring_to_str(s
));
371 void MPArea::keyReleaseEvent(QKeyEvent
*event
)
373 if (!event
->isAutoRepeat()) {
376 if (mp_keypress_throttle(0))
382 void MPArea::keyPressEvent(QKeyEvent
*event
)
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;
443 case Qt::Key_Enter
: ptr
= (wchar_t *) L
"ctrl-enter"; break;
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;
476 case Qt::Key_Enter
: ptr
= (wchar_t *) L
"enter"; break;
477 case Qt::Key_Escape
: ptr
= (wchar_t *) L
"escape"; break;
485 k
= qstring_to_str(event
->text());
492 if (mp_keypress_throttle(1))
497 void MPArea::mousePressEvent(QMouseEvent
*event
)
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;
517 mp_process_event(MPDM_S(ptr
));
523 void MPArea::mouseReleaseEvent(QMouseEvent
*event
)
529 void MPArea::mouseMoveEvent(QMouseEvent
*event
)
537 QPoint pos
= event
->pos();
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"));
555 void MPArea::wheelEvent(QWheelEvent
*event
)
557 if (event
->delta() > 0)
558 mp_process_event(MPDM_S(L
"mouse-wheel-up"));
560 mp_process_event(MPDM_S(L
"mouse-wheel-down"));
566 void MPArea::dragEnterEvent(QDragEnterEvent
*event
)
568 if (event
->mimeData()->hasFormat("text/uri-list"))
569 event
->acceptProposedAction();
573 void MPArea::dropEvent(QDropEvent
*event
)
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
++) {
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)
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"));
607 void MPArea::from_scrollbar(int value
)
609 if (!ignore_scrollbar_signal
) {
610 mpdm_t v
= mp_active();
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
));
623 void MPArea::from_filetabs(int value
)
626 /* sets the active one */
627 mpdm_hset_s(mp
, L
"active_i", MPDM_I(value
));
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
));
645 /** driver functions **/
647 static mpdm_t
qt4_drv_update_ui(mpdm_t a
)
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
);
667 static mpdm_t
qt4_drv_main_loop(mpdm_t a
)
675 static mpdm_t
qt4_drv_shutdown(mpdm_t a
)
679 if ((v
= mpdm_hget_s(mp
, L
"exit_message")) != NULL
) {
680 mpdm_write_wcs(stdout
, mpdm_string(v
));
688 static mpdm_t
qt4_drv_clip_to_sys(mpdm_t a
)
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
);
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));