blob: ae48abfe05f14693218a4c0c054f1a760fa40f1d [file] [log] [blame]
Bram Moolenaar843ee412004-06-30 16:16:41 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 */
8
9/*
10 * Porting to KDE(2) was done by
11 *
12 * (C) 2000 by Thomas Capricelli <orzel@freehackers.org>
13 *
14 * Please visit http://freehackers.org/kvim for other vim- or
15 * kde-related coding.
16 *
17 * $Id$
18 *
19 */
20
21#include <assert.h>
22#include <qpainter.h>
23#include <qevent.h>
24#include <qpushbutton.h>
25#include <qscrollbar.h>
26#include <qlayout.h>
27#include <qclipboard.h>
28#include <qdragobject.h>
29#include <qstrlist.h>
30#include <qmenubar.h>
31#include <qtextcodec.h>
32#if QT_VERSION>=300
33#include <qptrlist.h>
34#include <ktip.h>
35#endif
36#include <kglobal.h>
37#include <kconfig.h>
38#include <kaboutapplication.h>
39#include <dcopclient.h>
40#include <kaboutkde.h>
41#include <kbugreport.h>
42#include <kurldrag.h>
43#include <kmenubar.h>
44#include <ktoolbar.h>
45#include <kstandarddirs.h>
46#include "gui_kde_widget.h"
47#include <qxembed.h>
48
49extern "C" {
50#include "version.h"
51}
52
53// Pixmap for dialog
54#ifdef FEAT_GUI_DIALOG
55# include "../../pixmaps/alert.xpm"
56# include "../../pixmaps/error.xpm"
57# include "../../pixmaps/generic.xpm"
58# include "../../pixmaps/info.xpm"
59# include "../../pixmaps/quest.xpm"
60#endif
61
62/**
63 * Keycodes recognized by vim.
64 */
65struct special_key {//{{{
66 int qtkey;
67 char_u code0;
68 char_u code1;
69} special_keys[] =
70{
71 { Qt::Key_Up, 'k', 'u' },
72 { Qt::Key_Down, 'k', 'd' },
73 { Qt::Key_Left, 'k', 'l' },
74 { Qt::Key_Right, 'k', 'r' },
75 { Qt::Key_F1, 'k', '1' },
76 { Qt::Key_F2, 'k', '2' },
77 { Qt::Key_F3, 'k', '3' },
78 { Qt::Key_F4, 'k', '4' },
79 { Qt::Key_F5, 'k', '5' },
80 { Qt::Key_F6, 'k', '6' },
81 { Qt::Key_F7, 'k', '7' },
82 { Qt::Key_F8, 'k', '8' },
83 { Qt::Key_F9, 'k', '9' },
84 { Qt::Key_F10, 'k', ';' },
85 { Qt::Key_F11, 'F', '1' },
86 { Qt::Key_F12, 'F', '2' },
87 { Qt::Key_F13, 'F', '3' },
88 { Qt::Key_F14, 'F', '4' },
89 { Qt::Key_F15, 'F', '5' },
90 { Qt::Key_F16, 'F', '6' },
91 { Qt::Key_F17, 'F', '7' },
92 { Qt::Key_F18, 'F', '8' },
93 { Qt::Key_F19, 'F', '9' },
94 { Qt::Key_F20, 'F', 'A' },
95 { Qt::Key_F21, 'F', 'B' },
96 { Qt::Key_F22, 'F', 'C' },
97 { Qt::Key_F23, 'F', 'D' },
98 { Qt::Key_F24, 'F', 'E' },
99 { Qt::Key_F25, 'F', 'F' },
100 { Qt::Key_F26, 'F', 'G' },
101 { Qt::Key_F27, 'F', 'H' },
102 { Qt::Key_F28, 'F', 'I' },
103 { Qt::Key_F29, 'F', 'J' },
104 { Qt::Key_F30, 'F', 'K' },
105 { Qt::Key_F31, 'F', 'L' },
106 { Qt::Key_F32, 'F', 'M' },
107 { Qt::Key_F33, 'F', 'N' },
108 { Qt::Key_F34, 'F', 'O' },
109 { Qt::Key_F35, 'F', 'P' },
110 { Qt::Key_Help, '%', '1' },
111 // { Qt::Key_Undo, '&', '8' }, <= hmmm ?
112 { Qt::Key_BackSpace, 'k', 'b' },
113 { Qt::Key_Insert, KS_EXTRA, KE_KINS },
114 { Qt::Key_Delete, KS_EXTRA, KE_KDEL },
115 { Qt::Key_Home, 'K', '1' },
116 { Qt::Key_End, 'K', '4' },
117 { Qt::Key_Prior, 'K', '3' },
118 { Qt::Key_Next, 'K', '5' },
119 { Qt::Key_Print, '%', '9' },
120
121 { Qt::Key_Plus, 'K', '6'},
122 { Qt::Key_Minus, 'K', '7'},
123 { Qt::Key_Slash, 'K', '8'},
124 { Qt::Key_multiply, 'K', '9'},
125 { Qt::Key_Enter, 'K', 'A'},
126 { Qt::Key_Period, 'K', 'B'},
127
128 { Qt::Key_0, 'K', 'C'},
129 { Qt::Key_1, 'K', 'D'},
130 { Qt::Key_2, 'K', 'E'},
131 { Qt::Key_3, 'K', 'F'},
132 { Qt::Key_4, 'K', 'G'},
133 { Qt::Key_5, 'K', 'H'},
134 { Qt::Key_6, 'K', 'I'},
135 { Qt::Key_7, 'K', 'J'},
136 { Qt::Key_8, 'K', 'K'},
137 { Qt::Key_9, 'K', 'L'},
138 /* End of list marker: */
139 { 0, 0, 0 }
140};//}}}
141
142#ifdef FEAT_CLIENTSERVER
143typedef int (*QX11EventFilter) (XEvent*);
144extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
145static QX11EventFilter oldFilter = 0;
146static int kvim_x11_event_filter( XEvent* e);
147#endif
148void gui_keypress(QKeyEvent *e);
149
150/*
151 * Return OK if the key with the termcap name "name" is supported.
152 */
153 int
154gui_mch_haskey(char_u * name)//{{{
155{
156 for (int i=0; special_keys[i].qtkey != 0; i++)
157 if (name[0] == special_keys[i].code0 &&
158 name[1] == special_keys[i].code1)
159 return OK;
160 return FAIL;
161}//}}}
162
163/*
164 * custom Frame for drawing ...
165 */
166void VimWidget::paintEvent( QPaintEvent *e)//{{{
167{
168 QRect r = e->rect();
169 gui_redraw(r.x(), r.y(), r.width(), r.height() );
170}//}}}
171
172void VimWidget::draw_string(int x, int y, QString s, int len, int flags)//{{{
173{
174 gui.current_font->setBold( flags & DRAW_BOLD );
175 gui.current_font->setUnderline( flags & DRAW_UNDERL );
176 gui.current_font->setItalic(flags & DRAW_ITALIC);
177 painter->setBackgroundMode( flags & DRAW_TRANSP ? Qt::TransparentMode : Qt::OpaqueMode);
178 painter->setFont( *(gui.current_font) );
179 painter->drawText( x, y, s, len);
180}//}}}
181
182void VimWidget::mousePressEvent(QMouseEvent *event)//{{{
183{
184 int button=0;
185 int modifiers=0;
186 ButtonState state = event->state();
187 ButtonState buttons = event->button();
188
189 //Look at button states
190 if(buttons & QMouseEvent::LeftButton) {
191 button|=MOUSE_LEFT;
192 }
193 if(buttons & QMouseEvent::RightButton) {
194 button|=MOUSE_RIGHT;
195 }
196 if(buttons & QMouseEvent::MidButton) {
197 button|=MOUSE_MIDDLE;
198 }
199 //Look for keyboard modifiers
200 if(state & QMouseEvent::ShiftButton) {
201 modifiers|=MOUSE_SHIFT;
202 }
203 if(state & QMouseEvent::ControlButton){
204 modifiers|=MOUSE_CTRL;
205 }
206 if(state & QMouseEvent::AltButton){
207 modifiers|=MOUSE_ALT;
208 }
209 gui_send_mouse_event(button,event->x(),event->y(),FALSE,modifiers);
210#if QT_VERSION>=300
211 QByteArray params;
212 QDataStream stream(params, IO_WriteOnly);
213 stream << kapp->dcopClient()->appId() << button << modifiers << gui.row << gui.col;
214 kapp->dcopClient()->emitDCOPSignal("mousePEvent(QCString,int,int,int,int)", params);
215#endif
216 event->accept();
217}//}}}
218
219#if defined(FEAT_SESSION)
220void VimMainWindow::saveGlobalProperties (KConfig *conf)
221{
222 //we write a mksession file to a file written in the user's ~/.kde/share/config/
223 //the name of the file in saved in 'conf'
224 //when restoring app, we source this file
225#if 0 //disabled for release
226 QString filename = KGlobal::dirs()->localkdedir() + KGlobal::dirs()->kde_default("config") + kapp->randomString(10);
227 QString cmd("mksession ");
228 cmd+=filename;
229 do_cmdline_cmd((char_u*)cmd.latin1());
230 conf->writePathEntry("sessionfile", filename);
231 conf->sync();
232#endif
233}
234
235void VimMainWindow::readGlobalProperties (KConfig *conf)
236{
237#if 0
238 QString filename = conf->readPathEntry("sessionfile");
239 if (filename.isNull()) return;
240 QString cmd("source ");
241 cmd+=filename;
242 do_cmdline_cmd((char_u*)cmd.latin1());
243#endif
244}
245#endif
246
247void VimMainWindow::wheelEvent (QWheelEvent *event)//{{{
248{
249 ButtonState state = event->state();
250 int button=0;
251 int modifiers=0;
252
253 if (event->delta()>0)
254 button|=MOUSE_4;
255 else button|=MOUSE_5;
256
257 if(state & ShiftButton)
258 modifiers|=MOUSE_SHIFT;
259 if(state & ControlButton)
260 modifiers|=MOUSE_CTRL;
261 if(state & AltButton)
262 modifiers|=MOUSE_ALT;
263
264 gui_send_mouse_event(button,event->x(),event->y(),FALSE,modifiers);
265#if QT_VERSION>=300
266 QByteArray params;
267 QDataStream stream(params, IO_WriteOnly);
268 stream << kapp->dcopClient()->appId() << button << modifiers << gui.row << gui.col;
269 kapp->dcopClient()->emitDCOPSignal("mouseWhlEvent(QCString, int, int,int,int)", params);
270#endif
271 event->accept();
272}//}}}
273
274void VimWidget::mouseDoubleClickEvent(QMouseEvent *event)//{{{
275{
276 ButtonState state = event->state();
277 ButtonState buttons = event->button();
278 int modifiers=0;
279 int button=0;
280
281 //Look at button states
282 if(buttons & LeftButton)
283 button|=MOUSE_LEFT;
284 if(buttons & RightButton)
285 button|=MOUSE_RIGHT;
286 if(buttons & MidButton)
287 button|=MOUSE_MIDDLE;
288
289 //Look for keyboard modifiers
290 if(state & ShiftButton)
291 modifiers|=MOUSE_SHIFT;
292 if(state & ControlButton)
293 modifiers|=MOUSE_CTRL;
294 if(state & AltButton)
295 modifiers|=MOUSE_ALT;
296
297 gui_send_mouse_event(button,event->x(),event->y(),TRUE,modifiers);
298#if QT_VERSION>=300
299 QByteArray params;
300 QDataStream stream(params, IO_WriteOnly);
301 stream << kapp->dcopClient()->appId() << button << modifiers << gui.row << gui.col;
302 kapp->dcopClient()->emitDCOPSignal("mouseDblClickEvent(QCString, int, int,int,int)", params);
303#endif
304 event->accept();
305}//}}}
306
307void VimWidget::mouseMoveEvent(QMouseEvent *event){//{{{
308 ButtonState state = event->state();
309 int modifiers=0;
310 int button=0;
311
312 gui_mch_mousehide(FALSE);
313
314 //Look at button states
315 //warning: we use state here, this is important !
316 if(state & QMouseEvent::LeftButton || state & QMouseEvent::RightButton || state & QMouseEvent::MidButton)
317 button|=MOUSE_DRAG;
318
319 //Look for keyboard modifiers
320 if(state & ShiftButton)
321 modifiers|=MOUSE_SHIFT;
322 if(state & ControlButton)
323 modifiers|=MOUSE_CTRL;
324 if(state & AltButton)
325 modifiers|=MOUSE_ALT;
326 if (button!=MOUSE_DRAG)
327 gui_mouse_moved(event->x(),event->y());
328 else
329 gui_send_mouse_event(MOUSE_DRAG,event->x(),event->y(),FALSE,modifiers);
330}//}}}
331
332void VimWidget::mouseReleaseEvent(QMouseEvent *event)//{{{
333{
334 ButtonState state = event->state();
335 int modifiers=0;
336
337 //Look for keyboard modifiers
338 if(state & ShiftButton)
339 modifiers|=MOUSE_SHIFT;
340 if(state & ControlButton)
341 modifiers|=MOUSE_CTRL;
342 if(state & AltButton)
343 modifiers|=MOUSE_ALT;
344
345 gui_send_mouse_event(MOUSE_RELEASE,event->x(),event->y(),FALSE,modifiers);
346 event->accept();
347}//}}}
348
349/*
350 * The main widget (everything but toolbar/menubar)
351 */
352 VimWidget::VimWidget( QWidget *parent, const char *name, WFlags f )//{{{
353:QWidget(parent, name, f)
354 ,DCOPObject("KVim")
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +0000355#ifdef FEAT_MZSCHEME
356 ,mzscheme_timer_id(-1)
357#endif
Bram Moolenaar843ee412004-06-30 16:16:41 +0000358{
359 //to be able to show/hide the cursor when moving the mouse
360 setMouseTracking(true);
361 painter=new QPainter(this);
362
363 setKeyCompression(true);
364 setFocusPolicy( QWidget::StrongFocus );
365 setAcceptDrops(TRUE); // DND
366 blink_state = BLINK_NONE;
367 blink_on_time = 700;
368 blink_off_time = 400;
369 blink_wait_time = 250;
370 connect( &blink_timer, SIGNAL( timeout() ), SLOT( blink_cursor() ));
371 connect( &wait_timer, SIGNAL( timeout() ), SLOT ( wait_timeout() ));
372}//}}}
373
374void VimWidget::execNormal(QString command)//{{{
375{
376 QString cmd("execute 'normal ");
377 cmd+=command;
378 cmd+="'";
379 QCString unistring = vmw->codec->fromUnicode(cmd);
380 do_cmdline_cmd((char_u *)(const char*)unistring);
381 gui_update_screen();
382}//}}}
383
384void VimWidget::execInsert(QString command)//{{{
385{
386 QString cmd("execute 'normal i");
387 cmd+=command;
388 cmd+="'";
389 QCString unistring = vmw->codec->fromUnicode(cmd);
390 do_cmdline_cmd((char_u *)(const char*)unistring);
391 gui_update_screen();
392}//}}}
393
394void VimWidget::execRaw(QString command)//{{{
395{
396 QString cmd("execute '");
397 cmd+=command;
398 cmd+="'";
399 QCString unistring = vmw->codec->fromUnicode(cmd);
400 do_cmdline_cmd((char_u *)(const char*)unistring);
401 gui_update_screen();
402}//}}}
403
404void VimWidget::execCmd(QString command)//{{{
405{
406 QCString unistring = vmw->codec->fromUnicode(command);
407 do_cmdline_cmd((char_u *)(const char*)unistring);
408 gui_update_screen();
409}//}}}
410
411QString VimWidget::eval(QString expr)//{{{
412{
413#ifdef FEAT_EVAL
414 QCString unistring = vmw->codec->fromUnicode(expr);
415 QString val((const char *)eval_to_string((char_u *)(const char*)unistring,NULL));
416 return val;
417#else
418 return QString::null;
419#endif
420}//}}}
421
422void VimWidget::wait(long wtime)//{{{
423{
424 if ( wait_timer.isActive() ) wait_timer.stop();
425 wait_done = false;
426 wait_timer.start( wtime, true);
427}//}}}
428
429void VimWidget::wait_timeout() //{{{
430{
431 wait_done = true;
432}//}}}
433
434void VimWidget::dragEnterEvent (QDragEnterEvent *e)//{{{
435{
436#if (defined(FEAT_WINDOWS) && defined(HAVE_DROP_FILE)) || defined(PROTO)
437 e->accept(QUriDrag::canDecode(e));
438#else
439 e->ignore();
440#endif
441}//}}}
442
443void VimWidget::dropEvent (QDropEvent *e) // {{{
444{
445#if (defined(FEAT_WINDOWS) && defined(HAVE_DROP_FILE)) || defined(PROTO)
446 QStrList urls;
447
448 char_u **fnames;
449 int redo_dirs = FALSE;
450 int i;
451 int n;
452 int nfiles;
453 int url = FALSE;
454
455 /* Count how many items there may be and normalize delimiters. */
456
457 if (QUriDrag::decode(e, urls)) {
458 n = urls.count();
459 fnames = (char_u **)lalloc((n+1) * sizeof(char_u *), TRUE);
460 nfiles = 0;
461#if QT_VERSION>=300
462 QPtrListIterator<char> it(urls);
463 for( ; it.current(); ++it ) {
464 KURL u(*it);
465#else
466 for (i=0;i<urls.count();++i) {
467 KURL u(urls.at(i));
468#endif
469 if ( !u.isLocalFile() )
470 url = TRUE;
471 else {
472 fnames[nfiles] = (char_u *)strdup((const char *)u.path());
473 ++nfiles;
474 }
475 }
476 /* Real files (i.e. not http and not ftp) */
477 if (url == FALSE)
478 {
479 if (nfiles == 1)
480 {
481 if (mch_isdir(fnames[0]))
482 {
483 /* Handle dropping a directory on Vim. */
484 if (mch_chdir((char *)fnames[0]) == 0)
485 {
486 free(fnames[0]);
487 fnames[0] = NULL;
488 redo_dirs = TRUE;
489 }
490 }
491 } else {
492 /* Ignore any directories */
493 for (i = 0; i < nfiles; ++i)
494 {
495 if (mch_isdir(fnames[i]))
496 {
497 vim_free(fnames[i]);
498 fnames[i] = NULL;
499 }
500 }
501 }
502
503 if (0)
504 {
505 /* Shift held down, change to first file's directory */
506 if (fnames[0] != NULL && vim_chdirfile(fnames[0]) == OK)
507 redo_dirs = TRUE;
508 } else {
509 char_u dirname[MAXPATHL];
510 char_u *s;
511 if (mch_dirname(dirname, MAXPATHL) == OK)
512 for (i = 0; i < nfiles; ++i)
513 if (fnames[i] != NULL)
514 {
515 s = shorten_fname(fnames[i], dirname);
516 if (s != NULL && (s = vim_strsave(s)) != NULL)
517 {
518 vim_free(fnames[i]);
519 fnames[i] = s;
520 }
521 }
522 }
523 }
524
525 /* Handle the drop, :edit or :split to get to the file */
526 handle_drop(nfiles, fnames, FALSE);
527
528 if (redo_dirs)
529 shorten_fnames(TRUE);
530 }
531
532 /* Update the screen display */
533 update_screen(NOT_VALID);
534#ifdef FEAT_MENU
535 gui_update_menus(0);
536#endif
537 setcursor();
538 out_flush();
539 gui_update_cursor(FALSE, FALSE);
540 gui_mch_flush();
541#endif
542} // }}}
543
544void VimWidget::keyPressEvent( QKeyEvent *e ) // {{{
545{
546 gui_keypress(e);
547} // }}}
548
549void gui_keypress(QKeyEvent *e) { // {{{
550 int key = (int)e->key();
551 int modifiers = 0,i;
552 uchar string[256],string2[256];
553 uchar *s,*d;
554 Qt::ButtonState state = e->state();
555
556 QCString unistring = vmw->codec->fromUnicode(e->text());
557 if (unistring.length()>0)
558 strncpy((char*)string, (const char*)unistring,unistring.length());
559 string[unistring.length()] = 0;
560 int len=unistring.length();
561
562 // ignore certain keys
563 if (key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Control || key == Qt::Key_Meta
564 || key == Qt::Key_CapsLock || key == Qt::Key_NumLock || key == Qt::Key_ScrollLock ) {
565 e->ignore();
566 return;
567 }
568
569#ifdef FEAT_MBYTE
570 if (input_conv.vc_type != CONV_NONE)
571 {
572 mch_memmove(string2, string, len);
573 len = convert_input(string2, len, sizeof(string2));
574 s = string2;
575 }
576 else
577#endif
578 s = string;
579 d = string;
580 for (i = 0; i < len; ++i)
581 {
582 *d++ = s[i];
583 if (d[-1] == CSI && d + 2 < string + sizeof(string))
584 {
585 /* Turn CSI into K_CSI. */
586 *d++ = KS_EXTRA;
587 *d++ = (int)KE_CSI;
588 }
589 }
590 len = d - string;
591
592
593 // change shift-tab (backtab) into S_TAB
594 if ( key == Qt::Key_BackTab && state & Qt::ShiftButton) {
595 key = Qt::Key_Tab;
596 }
597
598 // Change C-@ and C-2 in NUL ? Gtk does this
599 if ( (key == Qt::Key_2 || key == Qt::Key_At)
600 && state & Qt::ControlButton ) {
601 string[0] = NUL;
602 len = 1;
603 }
604 else if (len == 0 && (key == Qt::Key_Space || key == Qt::Key_Tab))
605 {
606 /* When there are modifiers, these keys get zero length; we need the
607 * original key here to be able to add a modifier below. */
608 string[0] = (key & 0xff);
609 len = 1;
610 }
611 /* Check for Alt/Meta key (Mod1Mask), but not for a BS, DEL or character
612 * that already has the 8th bit set.
613 * Don't do this for <S-M-Tab>, that should become K_S_TAB with ALT. */
614 if (len == 1
615 && (key != Qt::Key_BackSpace && key != Qt::Key_Delete)
616 && (string[0] & 0x80) == 0
617 && (state & Qt::AltButton)
618 && !(key == Qt::Key_Tab && (state & Qt::ShiftButton)))
619 {
620 string[0] |= 0x80;
621#ifdef FEAT_MBYTE
622 if (enc_utf8) // convert to utf-8
623 {
624 string[1] = string[0] & 0xbf;
625 string[0] = ((unsigned)string[0] >> 6) + 0xc0;
626 if (string[1] == CSI)
627 {
628 string[2] = KS_EXTRA;
629 string[3] = (int)KE_CSI;
630 len = 4;
631 }
632 else
633 len = 2;
634 }
635#endif
636 }
637
638 /* Check for special keys, making sure BS and DEL are recognised. */
639 if (len == 0 || key == Qt::Key_BackSpace || key == Qt::Key_Delete)
640 {
641 while (special_keys[i].qtkey != 0 && special_keys[i].qtkey != key ) i++;
642 if (special_keys[i].qtkey != 0) {
643 string[0] = CSI;
644 string[1] = special_keys[i].code0;
645 string[2] = special_keys[i].code1;
646 len = -3;
647 }
648/*
649 for (i = 0; special_keys[i].qtkey != 0 ; i++)
650 {
651 if (special_keys[i].qtkey == key ) {
652 string[0] = CSI;
653 string[1] = special_keys[i].code0;
654 string[2] = special_keys[i].code1;
655 len = -3;
656 break;
657 }
658 }*/
659 }
660
661 if (len == 0) {
662 //no need to dump that, that's a QT problem, we can't do anything
663 //dbf("Unrecognised Key : %X %s", key, e->text().latin1());
664 e->ignore();
665 return;
666 }
667
668
669 /* Special keys (and a few others) may have modifiers */
670 if (len == -3 || key == Qt::Key_Space || key == Qt::Key_Tab ||
671 key == Qt::Key_Return || key == Qt::Key_Enter ||
672 key == Qt::Key_Escape) {
673
674 modifiers = 0;
675 if (state & Qt::ShiftButton) modifiers |= MOD_MASK_SHIFT;
676 if (state & Qt::ControlButton) modifiers |= MOD_MASK_CTRL;
677 if (state & Qt::AltButton) modifiers |= MOD_MASK_ALT;
678
679 /*
680 * For some keys a shift modifier is translated into another key
681 * code. Do we need to handle the case where len != 1 and
682 * string[0] != CSI?
683 */
684 if (len == -3)
685 key = TO_SPECIAL(string[1], string[2]);
686 else
687 key = string[0];
688
689 key = simplify_key(key, &modifiers);
690 if (key == CSI) key=K_CSI;
691
692 if (IS_SPECIAL(key)) {
693 string[0] = CSI;
694 string[1] = K_SECOND(key);
695 string[2] = K_THIRD(key);
696 len = 3;
697 } else {
698 string[0] = key;
699 len = 1;
700 }
701
702
703 if (modifiers!=0) {
704 uchar string2[10];
705 string2[0] = CSI;
706 string2[1] = KS_MODIFIER;
707 string2[2] = modifiers;
708 add_to_input_buf(string2, 3);
709 }
710
711 } /* special keys */
712
713 if (len == 1 && ((string[0] == Ctrl_C && ctrl_c_interrupts)
714 || (string[0] == intr_char && intr_char != Ctrl_C)))
715 {
716 trash_input_buf();
717 got_int = TRUE;
718 }
719
720 add_to_input_buf(string, len);
721 if (p_mh) {
722 gui_mch_mousehide(TRUE);
723 }
724 //DCOP Embedding stuff
725 //if we are here then the user has type something in the window, thus we can easily imagine that :
726 // 1 - text has changed (emit textChanged())
727 // 2 - characters were interactively inserted (emit charactersInteractivelyInserted())
728 // 3 - cursor position has changed ( emit cursorPositionChanged() )
729 // 4 - selection has changed ? dunno yet //XXX
730 // 5 - undo changed too ? (each character typed in makes the undo changes anyway)
731 // conclusion : this makes a lot of things to send to the vim kpart, maybe too much
732 // for now i'll just send : keyboardEvent to the kpart with the event string as parameter,
733 // with current current position
734 // i'll do the same for mouseEvents
735#if QT_VERSION>=300
736 QByteArray params;
737 QDataStream stream(params, IO_WriteOnly);
738 stream << kapp->dcopClient()->appId() << unistring << gui.row << gui.col;
739 kapp->dcopClient()->emitDCOPSignal("keyboardEvent(QCString, QCString,int,int)", params);
740#endif
741 e->ignore();
742} // }}}
743
744#ifdef FEAT_CLIENTSERVER
745void VimWidget::serverActivate(WId id) //{{{
746{
747 if (serverName == NULL && serverDelayedStartName != NULL) {
748 commWindow = id;
749 (void)serverRegisterName(qt_xdisplay(), serverDelayedStartName);
750 } else {
751 serverChangeRegisteredWindow( qt_xdisplay(), id );
752 }
753}//}}}
754#endif
755
756#ifdef FEAT_XIM
757void VimWidget::imStartEvent(QIMEvent *e) {
758 e->accept();
759}
760
761void VimWidget::imEndEvent(QIMEvent *e) {
762 uchar string[256];
763
764 QCString unistring = vmw->codec->fromUnicode(e->text());
765 if (unistring.length()>0)
766 strncpy((char*)string, (const char*)unistring,unistring.length());
767 string[unistring.length()] = 0;
768 int len=unistring.length();
769
770 add_to_input_buf(string, len);
771 e->accept();
772}
773
774void VimWidget::imComposeEvent(QIMEvent *e) {
775 //i should do something here, displaying the text somewhere ... (status area ?)
776 e->accept();
777}
778#endif
779
780
781void VimMainWindow::lock()
782{
783 locked=true;
784}
785
786void VimMainWindow::unlock()
787{
788 locked=false;
789}
790
791bool VimMainWindow::isLocked()
792{
793 return locked;
794}
795
796// ->resize VimWidget if not locked
797//
798void VimMainWindow::resizeEvent ( QResizeEvent *e ) //{{{
799{
800 if ( vmw->isLocked() ) return;
801 //remove toolbar and menubar height
802 int height = e->size().height();
803 int width = e->size().width();
804
805 if (vmw->menuBar()->isVisible() && vmw->menuBar()->isEnabled()
806#if QT_VERSION>=300
807 && !vmw->menuBar()->isTopLevelMenu()
808#endif
809 )
810 height -= vmw->menuBar()->height();
811#ifdef FEAT_TOOLBAR
812 if (vmw->toolBar()->isVisible() && vmw->toolBar()->isEnabled() &&
813 (vmw->toolBar()->barPos()==KToolBar::Top ||
814 vmw->toolBar()->barPos()==KToolBar::Bottom))
815 height -= vmw->toolBar()->height();
816
817 if (vmw->toolBar()->isVisible() && vmw->toolBar()->isEnabled() &&
818 (vmw->toolBar()->barPos()==KToolBar::Left ||
819 vmw->toolBar()->barPos()==KToolBar::Right))
820 width -= vmw->toolBar()->width();
821#endif
822 height = ( ((int)(height/gui.char_height))*gui.char_height );
823 if (!vmw->isLocked()) gui_resize_shell(width,height);
824}//}}}
825
826void VimWidget::focusInEvent( QFocusEvent * fe ) // {{{
827{
828 gui_focus_change(true);
829
830 if (blink_state == BLINK_NONE)
831 gui_mch_start_blink();
832} // }}}
833
834void VimWidget::focusOutEvent( QFocusEvent * fe )//{{{
835{
836 gui_focus_change(false);
837
838 if (blink_state != BLINK_NONE)
839 gui_mch_stop_blink();
840}//}}}
841
842void VimWidget::set_blink_time( long wait, long on, long off)//{{{
843{
844 blink_wait_time = wait;
845 blink_on_time = on;
846 blink_off_time = off;
847}//}}}
848
849void VimWidget::start_cursor_blinking()//{{{
850{
851 if (blink_timer.isActive()) blink_timer.stop();
852
853 /* Only switch blinking on if none of the times is zero */
854 if (blink_wait_time && blink_on_time && blink_off_time && gui.in_focus) {
855 blink_state = BLINK_ON;
856 gui_update_cursor(TRUE, FALSE);
857 // The first blink appears after wait_time
858 blink_timer.start( blink_wait_time, true);
859 }
860}//}}}
861
862void VimWidget::blink_cursor()//{{{
863{
864 if (blink_state == BLINK_ON) {
865 // set cursor off
866 gui_undraw_cursor();
867 blink_state = BLINK_OFF;
868 blink_timer.start( blink_off_time, true);
869 } else {
870 // set cursor on
871 gui_update_cursor(TRUE, FALSE);
872 blink_state = BLINK_ON;
873 blink_timer.start( blink_on_time, true);
874 }
875}//}}}
876
877void VimWidget::stop_cursor_blinking()//{{{
878{
879 if (blink_timer.isActive()) blink_timer.stop();
880
881 if (blink_state == BLINK_OFF)
882 gui_update_cursor(TRUE, FALSE);
883
884 blink_state = BLINK_NONE;
885}//}}}
886
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +0000887#ifdef FEAT_MZSCHEME
888void VimWidget::timerEvent( QTimerEvent * evnt)//{{{
889{
890 if (evnt->timerId() == mzscheme_timer_id)
891 timer_proc();
892}//}}}
893
894void VimWidget::enable_mzscheme_threads()//{{{
895{
896 mzscheme_timer_id = startTimer(p_mzq);
897}//}}}
898
899void VimWidget::disable_mzscheme_threads()//{{{
900{
901 killTimer(mzscheme_timer_id);
902}//}}}
903#endif
904
Bram Moolenaar843ee412004-06-30 16:16:41 +0000905void VimWidget::flash()//{{{
906{
907 QPainter p(this);
908
909 p.setRasterOp(Qt::XorROP);
910 p.fillRect(geometry(),QColor(0xFF,0xFF,0xFF));
911 p.flush();
912 //FIXME: Make this a little smarter. Maybe add a timer or something
913 usleep(19000);
914 p.fillRect(geometry(),QColor(0xFF,0xFF,0xFF));
915 p.flush();
916 p.end();
917}//}}}
918
919
920/*
921 * The main Window
922 */
923 VimMainWindow::VimMainWindow ( const char *name , WFlags f)//{{{
924:KMainWindow(0L, name,f)
925{
926#ifdef FEAT_CLIENTSERVER
927 oldFilter = qt_set_x11_event_filter( kvim_x11_event_filter );
928#endif
929 if (echo_wid_arg== 1) {
930 fprintf(stderr, "WID: %ld\n", (long)winId());
931 fflush(stderr);
932 }
933
934 w = new VimWidget(this, "main vim widget");
935 gui.w = w;
936 setFocusProxy(w);
937 w->setFocus();
938 have_tearoff=0;
939
940 finddlg=new KEdFind (this,0,false);
941 repldlg=new KEdReplace (this,0,false);
942 QObject::connect( finddlg, SIGNAL(search()), this, SLOT(slotSearch()) );
943 QObject::connect( repldlg, SIGNAL(find()), this, SLOT(slotFind()) );
944 QObject::connect( repldlg, SIGNAL(replace()), this, SLOT(slotReplace()) );
945 QObject::connect( repldlg, SIGNAL(replaceAll()), this, SLOT(slotReplaceAll()) );
946
947#ifdef FEAT_TOOLBAR
948 connect(toolBar(), SIGNAL(clicked(int)), this, SLOT(menu_activated(int)));
949#endif
950#ifdef FEAT_CLIENTSERVER
951 w->serverActivate(winId());
952
953 if (serverName!=NULL)
954 kapp->dcopClient()->registerAs(QCString((const char*)serverName),false);
955 else if (serverDelayedStartName!=NULL)
956 kapp->dcopClient()->registerAs(QCString((const char*)serverDelayedStartName),false);
957 else if (argServerName!=NULL)
958 kapp->dcopClient()->registerAs(argServerName->utf8(),false);
959#else
960 if (argServerName!=NULL)
961 kapp->dcopClient()->registerAs(argServerName->utf8(),false);
962#endif
963 QXEmbed::initialize();
964
965}//{{{
966
967bool VimMainWindow::queryClose()//{{{
968{
969 gui_shell_closed();
970 return true;
971}//}}}
972
973bool VimMainWindow::queryExit()//{{{
974{
975 return true;
976}//}}}
977
978void VimMainWindow::menu_activated(int dx)//{{{
979{
980#ifdef FEAT_MENU
981 if (!dx) { // tearoff
982 return;
983 }
984 gui_mch_set_foreground();
985 gui_menu_cb((VimMenu *) dx);
986#endif
987}//}}}
988
989
990void VimMainWindow::clipboard_selection_update(){//{{{
991 if(kapp->clipboard()->ownsSelection()) {
992 clip_own_selection(&clip_star);
993 } else {
994 clip_lose_selection(&clip_star);
995 }
996}//}}}
997
998void VimMainWindow::clipboard_data_update(){//{{{
999#if QT_VERSION>=300
1000 if (kapp->clipboard()->ownsClipboard()) {
1001 clip_own_selection(&clip_plus);
1002 } else {
1003 clip_lose_selection(&clip_plus);
1004 }
1005#else
1006 if (kapp->clipboard()->ownsSelection()) {
1007 clip_own_selection(&clip_star);
1008 } else {
1009 clip_lose_selection(&clip_star);
1010 }
1011#endif
1012}//}}}
1013
1014void VimMainWindow::slotSearch()//{{{
1015{
1016 QString find_text;
1017 bool direction_down = TRUE;
1018 bool casesensitive = TRUE;
1019 int flags = FRD_FINDNEXT;
1020
1021 find_text = finddlg->getText();
1022 direction_down = !(finddlg->get_direction());
1023 casesensitive = finddlg->case_sensitive();
1024 // if (casesensitive) find_text = "\\C" + find_text;
1025 // else find_text = "\\c" + find_text;
1026 if (casesensitive) flags|=FRD_MATCH_CASE;
1027 QCString unistring = vmw->codec->fromUnicode(find_text);
1028 gui_do_findrepl(flags, (char_u *)(const char *)unistring, NULL,(int)direction_down);
1029}//}}}
1030
1031void VimMainWindow::slotFind()//{{{
1032{
1033 QString find_text;
1034 bool direction_down=TRUE;
1035 bool casesensitive = TRUE;
1036 int flags = FRD_R_FINDNEXT;
1037
1038 find_text=repldlg->getText();
1039 direction_down = !(repldlg->get_direction());
1040 casesensitive = repldlg->case_sensitive();
1041 // if (casesensitive) find_text = "\\C" + find_text;
1042 // else find_text = "\\c" + find_text;
1043 if (casesensitive) flags|=FRD_MATCH_CASE;
1044
1045 QCString unistring = vmw->codec->fromUnicode(find_text);
1046 gui_do_findrepl(flags, (char_u *)(const char *)unistring, NULL,(int)direction_down);
1047}//}}}
1048
1049void VimMainWindow::slotReplace()//{{{
1050{
1051 QString find_text;
1052 QString repl_text;
1053 bool direction_down=TRUE;
1054 bool casesensitive = TRUE;
1055 int flags = FRD_REPLACE;
1056
1057 find_text=repldlg->getText();
1058 repl_text=repldlg->getReplaceText();
1059 direction_down = !(repldlg->get_direction());
1060 //if (casesensitive) find_text = "\\C" + find_text;
1061 //else find_text = "\\c" + find_text;
1062 if (casesensitive) flags|=FRD_MATCH_CASE;
1063
1064 QCString unistring = vmw->codec->fromUnicode(find_text);
1065 QCString unistring2 = vmw->codec->fromUnicode(repl_text);
1066 gui_do_findrepl(flags, (char_u *)(const char *)unistring,(char_u *)(const char*)unistring2,(int)direction_down);
1067}//}}}
1068
1069void VimMainWindow::slotReplaceAll()//{{{
1070{
1071 QString find_text;
1072 QString repl_text;
1073 bool direction_down=TRUE;
1074 bool casesensitive = TRUE;
1075 int flags = FRD_REPLACEALL;
1076
1077 find_text=repldlg->getText();
1078 repl_text=repldlg->getReplaceText();
1079 direction_down = !(repldlg->get_direction());
1080 casesensitive = repldlg->case_sensitive();
1081 // if (casesensitive) find_text = "\\C" + find_text;
1082 // else find_text = "\\c" + find_text;
1083 if (casesensitive) flags|=FRD_MATCH_CASE;
1084 QCString unistring = vmw->codec->fromUnicode(find_text);
1085 QCString unistring2 = vmw->codec->fromUnicode(repl_text);
1086 gui_do_findrepl(flags, (char_u *)(const char *)unistring,(char_u *)(const char*)unistring2,(int)direction_down);
1087}//}}}
1088
1089void VimMainWindow::showAboutKDE()
1090{
1091 KAboutKDE *kde = new KAboutKDE(this);
1092 kde->show();
1093}
1094
1095void VimMainWindow::showAboutApplication()//{{{
1096{
1097 KAboutData *aboutData = new KAboutData (
1098 "kvim"
1099 , I18N_NOOP("KVim")
1100 , VIM_VERSION_SHORT
1101 , I18N_NOOP("Vim in a KDE interface")
1102 , 0
1103 , "(c) Vim Team, \":help credits\" for more infos.\nType \":help iccf\" to see how you can help the children in Uganda"
1104 , 0l
1105 , "http://freehackers.org/kvim"
1106 , "kvim-dev@freenux.org"
1107 );
1108
1109 aboutData->addAuthor("Bram Moolenaar",
1110 I18N_NOOP("Main vim author"),
1111 "Bram@vim.org",
1112 "http://www.vim.org/");
1113 aboutData->addAuthor("Thomas Capricelli",
1114 I18N_NOOP("KDE porting"),
1115 "orzel@freehackers.org",
1116 "http://orzel.freehackers.org");
1117 aboutData->addAuthor("Philippe Fremy",
1118 I18N_NOOP("KDE porting"),
1119 "pfremy@chez.com",
1120 "http://www.freehackers.org/kvim");
1121 aboutData->addAuthor("Mark Westcott",
1122 I18N_NOOP("Qtopia porting, maintainer of the Qtopia part"),
1123 "mark@houseoffish.org",
1124 "http://houseoffish.org");
1125 aboutData->addAuthor("Mickael Marchand",
1126 I18N_NOOP("KDE porting, maintainer"),
1127 "marchand@kde.org",
1128 "http://freenux.org");
1129 aboutData->addAuthor("Many other people",
1130 I18N_NOOP("type :help credits for more infos")
1131 );
1132 aboutData->addCredit("Vince Negri",
1133 I18N_NOOP("Antialiasing support, Color fixes"),
1134 "vnegri@asl-electronics.co.uk");
1135 aboutData->addCredit("Malte Starostik",
1136 I18N_NOOP("Patch for performance improvement"),
1137 "malte@kde.org");
1138 aboutData->addCredit("Mark Stosberg",
1139 I18N_NOOP("Provided a FreeBSD box to debug KVim on BSD"),
1140 "mark@summersault.com"
1141 );
1142 aboutData->addCredit("Henrik Skott",
1143 I18N_NOOP("Font patch when KDE not configured"),
1144 "henrik.skott@hem.utfors.se"
1145 );
1146 aboutData->addCredit("Kailash Sethuraman",
1147 I18N_NOOP("NetBSD configure/compilation fixes")
1148 );
1149 aboutData->setLicenseText(
1150"KVim as an extension of Vim follows Vim license : \n\
1151Vim is Charityware. You can use and copy it as much as you like, but you are\n\
1152encouraged to make a donation to orphans in Uganda. Please read the file\n\
1153runtime/doc/uganda.txt for details.\n\
1154\n\
1155There are no restrictions on distributing an unmodified copy of Vim. Parts of\n\
1156Vim may also be distributed, but this text must always be included. You are\n\
1157allowed to include executables that you made from the unmodified Vim sources,\n\
1158your own usage examples and Vim scripts.\n\
1159\n\
1160If you distribute a modified version of Vim, you are encouraged to send the\n\
1161maintainer a copy, including the source code. Or make it available to the\n\
1162maintainer through ftp; let him know where it can be found. If the number of\n\
1163changes is small (e.g., a modified Makefile) e-mailing the diffs will do.\n\
1164When the maintainer asks for it (in any way) you must make your changes,\n\
1165including source code, available to him.\n\
1166\n\
1167The maintainer reserves the right to include any changes in the official\n\
1168version of Vim. This is negotiable. You are not allowed to distribute a\n\
1169modified version of Vim when you are not willing to make the source code\n\
1170available to the maintainer.\n\
1171\n\
1172The current maintainer is Bram Moolenaar <Bram@vim.org>. If this changes, it\n\
1173will be announced in appropriate places (most likely www.vim.org and\n\
1174comp.editors). When it is completely impossible to contact the maintainer,\n\
1175the obligation to send him modified source code ceases.\n\
1176\n\
1177It is not allowed to remove these restrictions from the distribution of the\n\
1178Vim sources or parts of it. These restrictions may also be used for previous\n\
1179Vim releases instead of the text that was included with it.");
1180
1181 KAboutApplication *about = new KAboutApplication(aboutData);
1182 about->show();
1183}//}}}
1184
1185void VimMainWindow::showTipOfTheDay() {
1186#if QT_VERSION>=300
1187 KTipDialog::showTip (vmw,QString::null,true);
1188#endif
1189}
1190
1191void VimMainWindow::buffersToolbar() {
1192
1193}
1194
1195void VimMainWindow::showBugReport() {
1196 KBugReport *bug= new KBugReport(this,true);
1197 bug->show();
1198}
1199/*
1200 * Vim Dialog
1201 *
1202 * Returns:
1203 * 0: Cancel
1204 * 1- : nb of the pressed button
1205 */
1206
1207VimDialog::VimDialog (int type, /* type of dialog *///{{{
1208 char_u * title, /* title of dialog */
1209 char_u * message, /* message text */
1210 char_u * buttons, /* names of buttons */
1211 int def_but, /* default button */
1212 char_u *textfield ) /* input field */
1213:QDialog(vmw, "vim generic dialog", true), // true is for "modal"
1214 mapper(this, "dialog signal mapper")
1215{
1216 /*
1217 * Create Icon
1218 */
1219 char ** icon_data;
1220 switch (type) {
1221 case VIM_GENERIC:
1222 icon_data = generic_xpm;
1223 break;
1224 case VIM_ERROR:
1225 icon_data = error_xpm;
1226 break;
1227 case VIM_WARNING:
1228 icon_data = alert_xpm;
1229 break;
1230 case VIM_INFO:
1231 icon_data = info_xpm;
1232 break;
1233 case VIM_QUESTION:
1234 icon_data = quest_xpm;
1235 break;
1236 default:
1237 icon_data = generic_xpm;
1238 };
1239 QLabel * icon = new QLabel( this );
1240 icon->setPixmap( QPixmap( (const char **) icon_data ) );
1241 icon->setFixedSize( icon->sizeHint() );
1242
1243 QLabel * text = new QLabel( (const char *)message, this );
1244 text->setAlignment( AlignHCenter | AlignVCenter | ExpandTabs );
1245
1246 QStringList buttonText = QStringList::split( DLG_BUTTON_SEP, (char *) buttons);
1247 int butNb = buttonText.count();
1248
1249 /*
1250 * Layout
1251 */
1252
1253 QVBoxLayout * vly = new QVBoxLayout( this, 5, 5 );
1254 QHBoxLayout * hly1 = new QHBoxLayout( vly, 5);
1255 hly1->addWidget( icon );
1256 hly1->addWidget( text );
1257 QHBoxLayout * hly3 = new QHBoxLayout ( vly , 5);
1258 if (textfield!=NULL) {
1259 entry = new QLineEdit((const char *)textfield,this);
1260 entry->setText((const char *)textfield);
1261 hly3->addWidget( entry );
1262 ret=textfield;
1263 } else entry=NULL;
1264
1265 QHBoxLayout * hly2 = new QHBoxLayout( vly, 15);
1266 QString s;
1267 QPushButton * pushButton = 0L;
1268 for( int i=0; i<butNb; i++) {
1269 s = buttonText[i];
1270 pushButton = new QPushButton(s, this );
1271 if (s.find('&') != -1) {
1272 pushButton->setAccel( s.at(s.find('&')+1).latin1() );
1273 }
1274
1275 hly2->addWidget( pushButton );
1276 if (i == def_but-1) {
1277 pushButton->setDefault( true );
1278 pushButton->setAutoDefault( true );
1279 setResult( i+1 );
1280 }
1281 connect(pushButton, SIGNAL(clicked()), &mapper, SLOT(map()));
1282 mapper.setMapping(pushButton, i+1);
1283 }
1284 connect( &mapper, SIGNAL(mapped(int)), this, SLOT(done(int)));
1285
1286 setCaption((const char *) title);
1287
1288 vly->activate();
1289}//}}}
1290
1291void VimDialog::done(int r) {
1292 if (entry!=NULL) {
1293 if (r) {
1294 QCString unistring=vmw->codec->fromUnicode(entry->text());
1295 STRCPY(ret,(const char*)unistring);
1296 } else
1297 *ret=NUL;
1298 }
1299 QDialog::done(r);
1300}
1301
1302/*
1303 * ScrollBar pool handling
1304 */
1305SBPool::SBPool(void)//{{{
1306 :mapper(this, "SBPool signal mapper")
1307{
1308 connect(&mapper, SIGNAL(mapped(int)), this, SLOT(sbUsed(int)));
1309}//}}}
1310
1311
1312void SBPool::create(GuiScrollbar * sb, int orient)//{{{
1313{
1314 switch(orient) {
1315 case SBAR_HORIZ:
1316 sb->w = new QScrollBar(QScrollBar::Horizontal, vmw);
1317 break;
1318 case SBAR_VERT:
1319 sb->w = new QScrollBar(QScrollBar::Vertical, vmw);
1320 break;
1321 default:
1322 sb->w = 0;
1323 return;
1324 }
1325
1326 connect(sb->w, SIGNAL(valueChanged(int)), &mapper, SLOT(map()));
1327 mapper.setMapping(sb->w, (int)sb);
1328}//}}}
1329
1330
1331void SBPool::sbUsed(int who)//{{{
1332{
1333 GuiScrollbar *sb = (GuiScrollbar*)who;
1334 gui_drag_scrollbar( sb, sb->w->value(), FALSE);
1335}//}}}
1336
1337
1338void SBPool::destroy(GuiScrollbar * sb)//{{{
1339{
1340 if (!sb->w) return;
1341
1342 delete sb->w;
1343 sb->w = 0;
1344}//}}}
1345
1346#ifdef FEAT_CLIENTSERVER
1347static int kvim_x11_event_filter( XEvent* e)//{{{
1348{
1349 if (e->xproperty.type == PropertyNotify
1350 && e->xproperty.atom == commProperty
1351 && e->xproperty.window == commWindow
1352 && e->xproperty.state == PropertyNewValue ) {
1353 serverEventProc(qt_xdisplay(), e);
1354 }
1355
1356 if (oldFilter) return oldFilter( e );
1357 return FALSE;
1358}//}}}
1359#endif
1360
1361//add some QT 3 fonts usefull functions
1362#if QT_VERSION<300
1363QString KVimUtils::toString(QFont *f)
1364{
1365 QStringList l;
1366 l.append(f->family());
1367 l.append(QString::number(f->pointSize()));
1368 l.append(QString::number(f->pixelSize()));
1369 l.append(QString::number((int)f->styleHint()));
1370 l.append(QString::number(f->weight()));
1371 l.append(QString::number((int)f->italic()));
1372 l.append(QString::number((int)f->underline()));
1373 l.append(QString::number((int)f->strikeOut()));
1374 l.append(QString::number((int)f->fixedPitch()));
1375 l.append(QString::number((int)f->rawMode()));
1376 return l.join(",");
1377}
1378
1379bool KVimUtils::fromString(QFont *f, QString descrip)
1380{
1381 QStringList l(QStringList::split(',', descrip));
1382
1383 int count = l.count();
1384 if (count != 10 && count != 9) {
1385 return FALSE;
1386 }
1387
1388 f->setFamily(l[0]);
1389 f->setPointSize(l[1].toInt());
1390 if ( count == 9 ) {
1391 f->setStyleHint((QFont::StyleHint) l[2].toInt());
1392 f->setWeight(l[3].toInt());
1393 f->setItalic(l[4].toInt());
1394 f->setUnderline(l[5].toInt());
1395 f->setStrikeOut(l[6].toInt());
1396 f->setFixedPitch(l[7].toInt());
1397 f->setRawMode(l[8].toInt());
1398 } else {
1399 f->setPixelSize(l[2].toInt());
1400 f->setStyleHint((QFont::StyleHint) l[3].toInt());
1401 f->setWeight(l[4].toInt());
1402 f->setItalic(l[5].toInt());
1403 f->setUnderline(l[6].toInt());
1404 f->setStrikeOut(l[7].toInt());
1405 f->setFixedPitch(l[8].toInt());
1406 f->setRawMode(l[9].toInt());
1407 }
1408 return TRUE;
1409}
1410#endif
1411
1412QString KVimUtils::convertEncodingName(QString name)
1413{
1414 if (name.startsWith("ucs") || name.startsWith("utf-16")) return QString("utf16");
1415 if (name=="cp950") return QString("Big5");
1416 return QString();
1417}