# HG changeset patch # User vimboss # Date 1104526571 0 # Node ID af1bcb9a13c04895b0fa1fb8b876e07b4eab3872 # Parent f55897d6921d622ac2649e4c94ddb38d121c2832 updated for version 7.0027 diff --git a/pixmaps/tb_print.xpm b/pixmaps/tb_print.xpm --- a/pixmaps/tb_print.xpm +++ b/pixmaps/tb_print.xpm @@ -5,19 +5,19 @@ static char * tb_print_xpm[] = { /* colors */ " s none m none c none", ". s iconColor1 m black c #000000", -"X s iconColor2 m none c #FFFFFF", -"o s iconGray2 m none c #bdbdbd", +"X s iconColor2 m none c #FFFFFF", +"o s iconGray2 m none c #bdbdbd", "O s iconGray5 m black c #737373", "+ s bottomShadowColor m black c #5D6069", "@ c #FF1144", /* pixels */ " ....... ", " .XXXXX.. ", -" .X...X.X. ", +" .XXXXX.X. ", " .XXXXX.... ", -" .X...XXXX.O ", -" .XXXXXXXX.O ", -" .X.....XX.O ", +" .XXXXXXXX. ", +" .XXXXXXXX. ", +" ..XXXXXXXX.. ", " .XXXXXXXX.O ", "................ ", ".XXXXXXXXXXXXXO. ", diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt --- a/runtime/doc/help.txt +++ b/runtime/doc/help.txt @@ -1,4 +1,4 @@ -*help.txt* For Vim version 7.0aa. Last change: 2004 Jul 05 +*help.txt* For Vim version 7.0aa. Last change: 2004 Dec 30 VIM - main help file k @@ -189,12 +189,6 @@ Standard plugins ~ |pi_expl.txt| File explorer LOCAL ADDITIONS: *local-additions* -|engspchk.txt| English Spelling Checker (v57) May 25, 2004 -|example.txt| Example for a locally added help file -|matchit.txt| Extended "%" matching -|test.txt| Testing the hélp cömmĺnd nôw -|typecorr.txt| Plugin for correcting typing mistakes -|helpp.txt| Dummy line to avoid an error message ------------------------------------------------------------------------------ *bars* Bars example diff --git a/runtime/lang/menu_pl_pl.utf-8.vim b/runtime/lang/menu_pl_pl.utf-8.vim new file mode 100644 --- /dev/null +++ b/runtime/lang/menu_pl_pl.utf-8.vim @@ -0,0 +1,261 @@ +" Menu Translations: Polish +" Maintainer: Rafal M. Sulejman +" Initial Translation: Marcin Dalecki +" Last Change: 06 Sep 2001 + +" Quit when menu translations have already been done. +if exists("did_menu_trans") + finish +endif +let did_menu_trans = 1 + +scriptencoding iso-8859-2 + +" Help menu +menutrans &Help Po&moc +menutrans &Overview &Spis\ Treści +menutrans &How-to\ links &Odnośniki\ JTZ +menutrans &Credits Po&dziękowania +menutrans &User\ Manual Podręcznik\ &użytkownika +menutrans Co&pying &Kopiowanie +menutrans &Version &Wersja +menutrans &About o\ &Aplikacji + +" File menu +menutrans &File &Plik +menutrans &Open\.\.\.:e &Otwórz\.\.\.:e +menutrans Sp&lit-Open\.\.\.:sp Otwórz\ z\ &podziałem\.\.\.:sp +menutrans &New:enew &Nowy:enew +menutrans &Close:close &Zamknij:close +menutrans &Save:w Za&pisz:w +menutrans Save\ &As\.\.\.:sav Zapisz\ &jako\.\.\.:sav +menutrans Split\ &Diff\ with\.\.\. Podziel\ na\ diff-a\ między\.\.\. +menutrans Split\ Patched\ &By\.\.\. Podziel\ łatane\ przez\.\.\. +menutrans &Print &Drukuj +menutrans Sa&ve-Exit:wqa Zapisz\ i\ w&yjdź:wqa +menutrans E&xit:qa &Wyjście:qa + +" Edit menu +menutrans &Edit &Edycja +menutrans &Undou &Cofniju +menutrans &Redo^R &Ponów^R +menutrans Rep&eat\. P&owtórz\. +menutrans Cu&t"+x W&ytnij"+x +menutrans &Copy"+y &Kopiuj"+y +menutrans &Paste"+gP &Wklej"+gP +menutrans Put\ &Before[p Wstaw\ p&rzed[p +menutrans Put\ &After]p Wstaw\ p&o]p +menutrans &Select\ allggVG Z&aznacz\ całośćggVG +menutrans &Find\.\.\. &Szukaj\.\.\. +menutrans &Find/ &Szukaj/ +menutrans Find\ and\ Rep&lace\.\.\. &Zamień\.\.\. +menutrans Find\ and\ Rep&lace:%s &Zamień:%s +menutrans Find\ and\ Rep&lace &Zamień +menutrans Find\ and\ Rep&lace:s &Zamień:s +menutrans Options\.\.\. Opcje\.\.\. +menutrans Settings\ &Window Ustawienia +menutrans &Global\ Settings Ustawienia\ &globalne +menutrans F&ile\ Settings Ustawienia\ dla\ pliku +menutrans Toggle\ Line\ &Numbering:set\ nu! &Numerowanie\ wierszy:set\ nu! +menutrans Toggle\ &List\ Mode:set\ list! Tryb\ &listowania:set\ list! +menutrans Toggle\ Line\ &Wrap:set\ wrap! Za&wijanie\ wierszy:set\ wrap! +menutrans Toggle\ W&rap\ at\ word:set\ lbr! Łamanie\ wie&rsza:set\ lbr! +menutrans Toggle\ &expand-tab:set\ et! Rozwijani&e\ tabulatorów:set\ et! +menutrans Toggle\ &auto-indent:set\ ai! &Automatyczne\ wcięcia:set\ ai! +menutrans Toggle\ &C-indenting:set\ cin! Wcięcia\ &C:set\ cin! +menutrans &Shiftwidth &Szerokość\ wcięcia +menutrans Te&xt\ Width\.\.\. Długość\ linii\.\.\. +menutrans &File\ Format\.\.\. &Format\ pliku\.\.\. +menutrans Soft\ &Tabstop Rozmiar\ &tabulacji +menutrans C&olor\ Scheme Zestawy\ kolorów +menutrans &Keymap Układy\ klawiatury +menutrans None żaden +menutrans accents akcenty +menutrans hebrew hebrajski +menutrans hebrewp hebrajski\ p +menutrans russian-jcuken rosyjski-jcuken +menutrans russian-jcukenwin rosyjski-jcukenwin +menutrans russian-yawerty rosyjski-yawerty + +menutrans Toggle\ Pattern\ &Highlight:set\ hls! Podkreślanie\ &wzorców:set\ hls! + +menutrans Toggle\ &Ignore-case:set\ ic! &Ignorowanie\ wielkości:set\ ic! +menutrans Toggle\ &Showmatch:set\ sm! &Pokazywanie\ pasujących:set\ sm! + +menutrans &Context\ lines Wiersze\ &kontekstowe +menutrans &Virtual\ Edit Obróbka\ &wirtualna + +menutrans Never Nigdy +menutrans Block\ Selection Zaznaczanie\ zakresu +menutrans Insert\ mode Tryb\ wprowadzania +menutrans Block\ and\ Insert Zakres\ i\ wprowadzanie +menutrans Always Zawsze + +menutrans Toggle\ Insert\ &Mode:set\ im! Tryb\ wprowadzania:set\ im! +menutrans Search\ &Path\.\.\. Scieżka\ poszukiwania\.\.\. +menutrans Ta&g\ Files\.\.\. Pliki\ tagów\.\.\. + + +" +" GUI options +menutrans Toggle\ &Toolbar Pasek\ narzędzi +menutrans Toggle\ &Bottom\ Scrollbar Dolny\ przewijacz +menutrans Toggle\ &Left\ Scrollbar &Lewy\ przewijacz +menutrans Toggle\ &Right\ Scrollbar P&rawy\ przewijacz + +" Programming menu +menutrans &Tools &Narzędzia +menutrans &Jump\ to\ this\ tagg^] &Skocz\ do\ tagag^] +menutrans Jump\ &back^T Skok\ w\ &tył^T +menutrans Build\ &Tags\ File &Twórz\ plik\ tagów +" Folding +menutrans &Folding &Zwijanie +menutrans &Enable/Disable\ foldszi &Zwiń/rozwińzi +menutrans &View\ Cursor\ Linezv &Linia\ kursorazv +menutrans Vie&w\ Cursor\ Line\ onlyzMzx &Tylko\ linia\ kursorazMzx +menutrans C&lose\ more\ foldszm Zwiń\ więcejzm +menutrans &Close\ all\ foldszM Z&wiń\ wszystkiezM +menutrans &Open\ all\ foldszR Rozwiń\ wszystkiezR +menutrans O&pen\ more\ foldszr R&ozwiń\ więcejzr + +menutrans Create\ &Foldzf T&wórz\ zawinięciezf +menutrans &Delete\ Foldzd U&suń\ zawinięciezd +menutrans Delete\ &All\ FoldszD &Usuń\ wszystkie\ zawinięciazD +menutrans Fold\ column\ &width Szerokość\ kolumny\ za&winięć +menutrans Fold\ Met&hod Me&toda\ zawijania +menutrans M&anual &Ręcznie +menutrans I&ndent W&cięcie +menutrans E&xpression W&yrazenie +menutrans S&yntax S&kładnia +menutrans Ma&rker Zn&acznik + +" Diff +menutrans &Update &Odśwież +menutrans &Get\ Block &Pobierz\ blok +menutrans &Put\ Block &Wstaw\ blok + +" Make and stuff... +menutrans &Make:make M&ake:make +menutrans &List\ Errors:cl &Pokaż\ błędy:cl +menutrans L&ist\ Messages:cl! W&ylicz\ powiadomienia:cl! +menutrans &Next\ Error:cn &Następny\ błąd:cn +menutrans &Previous\ Error:cp &Poprzedni\ błąd:cp +menutrans &Older\ List:cold &Starsza\ lista:cold +menutrans N&ewer\ List:cnew N&owsza\ lista:cnew +menutrans Error\ &Window Okno\ komu&nikatów +menutrans &Update:cwin Akt&ualizuj:cwin +menutrans &Close:cclose &Zamknij:cclose +menutrans &Open:copen &Otwórz:copen + +menutrans &Set\ Compiler U&staw\ kompilator +menutrans &Convert\ to\ HEX:%!xxd Kody\ szesnastkowe:%!xxd +menutrans Conve&rt\ back:%!xxd\ -r Zwykły\ tekst:%!xxd\ -r + +" Names for buffer menu. +menutrans &Buffers &Bufory +menutrans &Refresh\ menu Odśwież +menutrans Delete Skasuj +menutrans &Alternate &Zmień +menutrans &Next &Następny +menutrans &Previous &Poprzedni +menutrans [No\ File] [Brak\ Pliku] + +" Window menu +menutrans &Window &Widoki +menutrans &New^Wn &Nowy^Wn +menutrans S&plit^Ws Po&dziel^Ws +menutrans Sp&lit\ To\ #^W^^ P&odziel\ na\ #^W^^ +menutrans Split\ &Vertically^Wv Podziel\ pionowo^Wv +menutrans Split\ File\ E&xplorer Otwórz\ menedżer\ plików + +menutrans &Close^Wc &Zamknij^Wc +menutrans Close\ &Other(s)^Wo Zamknij\ &inne^Wo +menutrans Ne&xt^Ww &Następny^Ww +menutrans P&revious^WW &Poprzedni^WW +menutrans &Equal\ Size^W= &Wyrównaj\ wysokości^W= +menutrans &Max\ Height^W_ Z&maksymalizuj\ wysokość^W_ +menutrans M&in\ Height^W1_ Zminim&alizuj\ wysokość^W1_ +menutrans Max\ Width^W\| Maksymalna\ szerokość^W\| +menutrans Min\ Width^W1\| Minimalna\ szerokość^W1\| +menutrans Max\ &Width^W\| Zmaksymalizuj\ szerokość^W\| +menutrans Min\ Widt&h^W1\| Zminimalizuj\ szerokość^W1\| +menutrans Move\ &To &Idź\ do +menutrans &Top^WK &Góra^WK +menutrans &Bottom^WJ &Dół^WJ +menutrans &Left\ side^WH &Lewa\ strona^WH +menutrans &Right\ side^WL &Prawa\ strona^WL +menutrans Rotate\ &Up^WR Obróć\ w\ &górę^WR +menutrans Rotate\ &Down^Wr Obróć\ w\ &dół^Wr +menutrans Split\ &Vertically^Wv &Podziel\ w\ poziomie^Wv +menutrans Select\ Fo&nt\.\.\. Wybierz\ &czcionkę\.\.\. + +" The popup menu +menutrans &Undo &Cofnij +menutrans Cu&t W&ytnij +menutrans &Copy &Kopiuj +menutrans &Paste &Wklej +menutrans &Delete &Skasuj +menutrans Select\ Blockwise Zaznacz\ &blok +menutrans Select\ &Word Zaznacz\ &słowo +menutrans Select\ &Line Zaznacz\ w&iersz +menutrans Select\ &Block Zaznacz\ &blok +menutrans Select\ &All Zaznacz\ c&ałość + +" The GUI toolbar +if has("toolbar") + if exists("*Do_toolbar_tmenu") + delfun Do_toolbar_tmenu + endif + fun Do_toolbar_tmenu() + tmenu ToolBar.Open Otwórz plik + tmenu ToolBar.Save Zapisz bieżący plik + tmenu ToolBar.SaveAll Zapisz wszystkie pliki + tmenu ToolBar.Print Drukuj + tmenu ToolBar.Undo Cofnij + tmenu ToolBar.Redo Ponów + tmenu ToolBar.Cut Wytnij + tmenu ToolBar.Copy Skopiuj + tmenu ToolBar.Paste Wklej + tmenu ToolBar.Find Szukaj... + tmenu ToolBar.FindNext Szukaj następnego + tmenu ToolBar.FindPrev Szukaj poprzedniego + tmenu ToolBar.Replace Szukaj i zamieniaj... + if 0 " disabled; These are in the Windows menu + tmenu ToolBar.New Nowy widok + tmenu ToolBar.WinSplit Podziel widok + tmenu ToolBar.WinMax Zmaksymalizuj widok + tmenu ToolBar.WinMin Zminimalizuj widok + tmenu ToolBar.WinClose Zamknij widok + endif + tmenu ToolBar.LoadSesn Załaduj sesję + tmenu ToolBar.SaveSesn Zachowaj bieżącą sesję + tmenu ToolBar.RunScript Uruchom skrypt Vima + tmenu ToolBar.Make Wykonaj bieżący projekt + tmenu ToolBar.Shell Otwórz powłokę + tmenu ToolBar.RunCtags Twórz tagi w bieżącym katalogu + tmenu ToolBar.TagJump Skok do taga pod kursorem + tmenu ToolBar.Help Pomoc Vima + tmenu ToolBar.FindHelp Przeszukuj pomoc Vim-a + endfun +endif + +" Syntax menu +menutrans &Show\ filetypes\ in\ menu &Pokazuj\ rodzaj\ pliku\ w\ menue +menutrans &Syntax &Składnia +menutrans Set\ '&syntax'\ only Ustaw\ tylko\ '&syntax' +menutrans Set\ '&filetype'\ too Ustaw\ również\ '&filetype' +menutrans &Off &Wyłącz +menutrans &Manual &Ręcznie +menutrans A&utomatic A&utomatyczne +menutrans on/off\ for\ &This\ file włącz/w&yłącz\ dla\ pliku +menutrans Co&lor\ test Test\ &kolorów +menutrans &Highlight\ test &Test\ podświetlania +menutrans &Convert\ to\ HTML Przetwórz\ na\ &HTML + +" dialog texts +let menutrans_no_file = "[Brak pliku]" +let menutrans_help_dialog = "Wprowadź komendę lub słowo, aby otrzymać pomoc o:\n\nPrzedrostek i_ oznacza komendę trybu Wprowadzania (np. i_CTRL-X)\nPrzedrostek c_ oznacza komendę edycji wiersza komend (np. c_)\nPrzedrostek ' oznacza nazwę opcji (np. 'shiftwidth')" +let g:menutrans_path_dialog = "Wprowadź ścieżkę poszukiwania plików.\nProszę rozdzielać nazwy katalogów przecinkiem." +let g:menutrans_tags_dialog = "Podaj nazwy plików tagów.\nProszę rozdzielać nazwy przecinkiem." +let g:menutrans_textwidth_dialog = "Wprowadź nową szerokość tekstu (0 wyłącza przewijanie): " +let g:menutrans_fileformat_dialog = "Wybierz format w którym ten plik ma być zapisany" diff --git a/runtime/menu.vim b/runtime/menu.vim --- a/runtime/menu.vim +++ b/runtime/menu.vim @@ -382,7 +382,7 @@ if has("keymap") endif unlet s:n endif -if has("win32") || has("win16") || has("gui_gtk") || has("gui_kde") || has("gui_photon") || has("gui_mac") +if has("win32") || has("win16") || has("gui_motif") || has("gui_gtk") || has("gui_kde") || has("gui_photon") || has("gui_mac") an 20.470 &Edit.Select\ Fo&nt\.\.\. :set guifont=* endif diff --git a/runtime/plugin/tar.vim b/runtime/plugin/tar.vim new file mode 100644 --- /dev/null +++ b/runtime/plugin/tar.vim @@ -0,0 +1,185 @@ +" vim:set ts=4 sw=4 ai nobackup: + +" tar.vim -- a vim plugin for browsing tarfiles +" Copyright (c) 2002, Michael C. Toren +" +" Updates are available from . If you +" find this script useful, or have suggestions for improvements, please +" let me know. +" +" Usage: +" Once this script is installed, attempting to edit a tarfile will present +" the user with a list of files contained in the tar archive. By moving the +" cursor over a filename and pressing ENTER, the contents of a file can be +" viewed in read-only mode, in a new window. Unfortunately, write support +" for tarfile components is not currently possible. +" +" Requirements: +" GNU tar, or a tar implementation that supports the "P" (don't strip +" out leading /'s from filenames), and "O" (extract files to standard +" output) options. Additionally, gzip is required for handling *.tar.Z, +" *.tar.gz, and *.tgz compressed tarfiles, and bzip2 is required for +" handling *.tar.bz2 compressed tarfiles. A unix-like operating system +" is probably also required. +" +" Installation: +" Place this file, tar.vim, in your $HOME/.vim/plugin directory, and +" either restart vim, or execute ":source $HOME/.vim/plugin/tar.vim" +" +" Todo: +" - Handle zipfiles? +" - Implement write support, somehow. +" +" License: +" This program is free software; you can redistribute it and/or modify it +" under the terms of the GNU General Public License, version 2, as published +" by the Free Software Foundation. +" +" This program is distributed in the hope that it will be useful, but +" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +" or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +" for more details. +" +" A copy of the GNU GPL is available as /usr/doc/copyright/GPL on Debian +" systems, or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html +" You can also obtain it by writing to the Free Software Foundation, Inc., +" 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +" +" Changelog: +" Tue Dec 31 13:38:08 EST 2002 First release to beta testers +" Sat Jan 4 14:06:19 EST 2003 Version 1.00 released + +let s:version = "1.00" + +if has("autocmd") +augroup tar + au! + au BufReadCmd tarfile:* call s:TarRead(expand(""), 1) + au BufReadCmd tarfile:*/* call s:TarRead(expand(""), 1) + au FileReadCmd tarfile:* call s:TarRead(expand(""), 0) + au FileReadCmd tarfile:*/* call s:TarRead(expand(""), 0) + + au BufWriteCmd tarfile:* call s:TarWrite(expand("")) + au BufWriteCmd tarfile:*/* call s:TarWrite(expand("")) + au FileWriteCmd tarfile:* call s:TarWrite(expand("")) + au FileWriteCmd tarfile:*/* call s:TarWrite(expand("")) + + au BufReadCmd *.tar call s:TarBrowse(expand("")) + au BufReadCmd *.tar.gz call s:TarBrowse(expand("")) + au BufReadCmd *.tar.bz2 call s:TarBrowse(expand("")) + au BufReadCmd *.tar.Z call s:TarBrowse(expand("")) + au BufReadCmd *.tgz call s:TarBrowse(expand("")) +augroup END +endif + +function! s:TarWrite(argument) + echo "ERROR: Sorry, no write support for tarfiles yet" +endfunction + +function! s:TarRead(argument, cleanup) + let l:argument = a:argument + let l:argument = substitute(l:argument, '^tarfile:', '', '') + let l:argument = substitute(l:argument, '^\~', $HOME, '') + + let l:tarfile = l:argument + while 1 + if (l:tarfile == "" || l:tarfile == "/") + echo "ERROR: Could not find a readable tarfile in path:" l:argument + return + endif + + if filereadable(l:tarfile) " found it! + break + endif + + let l:tarfile = fnamemodify(l:tarfile, ":h") + endwhile + + let l:toextract = strpart(l:argument, strlen(l:tarfile) + 1) + + if (l:toextract == "") + return + endif + + let l:cat = s:TarCatCommand(l:tarfile) + execute "r !" . l:cat . " < '" . l:tarfile . "'" + \ " | tar OPxf - '" . l:toextract . "'" + + if (a:cleanup) + 0d "blank line + execute "doautocmd BufReadPost " . expand("%") + setlocal readonly + silent preserve + endif +endfunction + +function! s:TarBrowse(tarfile) + setlocal noswapfile + setlocal buftype=nofile + setlocal bufhidden=hide + setlocal filetype= + setlocal nobuflisted + setlocal buftype=nofile + setlocal wrap + + let l:tarfile = a:tarfile + let b:tarfile = l:tarfile + let l:cat = s:TarCatCommand(l:tarfile) + + if ! filereadable(l:tarfile) + let l:tarfile = substitute(l:tarfile, '^tarfile:', '', '') + endif + + if ! filereadable(l:tarfile) + echo "ERROR: File not readable:" l:tarfile + return + endif + + call s:Say("\" tar.vim version " . s:version) + call s:Say("\" Browsing tarfile " . l:tarfile) + call s:Say("\" Hit ENTER to view contents in new window") + call s:Say("") + + silent execute "r!" . l:cat . "<'" . l:tarfile . "'| tar Ptf - " + 0d "blank line + /^$/1 + + setlocal readonly + setlocal nomodifiable + noremap :call TarBrowseSelect() +endfunction + +function! s:TarBrowseSelect() + let l:line = getline(".") + + if (l:line =~ '^" ') + return + endif + + if (l:line =~ '/$') + echo "Please specify a file, not a directory" + return + endif + + let l:selection = "tarfile:" . b:tarfile . "/" . l:line + new + wincmd _ + execute "e " . l:selection +endfunction + +" kludge to deal with compressed archives +function! s:TarCatCommand(tarfile) + if a:tarfile =~# '\.\(gz\|tgz\|Z\)$' + let l:cat = "gzip -d -c" + elseif a:tarfile =~# '\.bz2$' + let l:cat = "bzip2 -d -c" + else + let l:cat = "cat" + endif + return l:cat +endfunction + +function! s:Say(string) + let @" = a:string + $ put +endfunction diff --git a/runtime/syntax/named.vim b/runtime/syntax/named.vim --- a/runtime/syntax/named.vim +++ b/runtime/syntax/named.vim @@ -2,8 +2,9 @@ " Language: BIND 8.x configuration file " Maintainer: glory hump " Last change: Mon May 21 04:51:01 SAMST 2001 +" Updated: by Martin Dalecki 2004-12-31 " Filenames: named.conf -" URL: http://rnd.web-drive.ru/vim/syntax/named.vim +" URL: http://rnd.web-drive.ru/vim/syntax/named.vim [DEFUNCT] " $Id$ " " NOTE @@ -33,10 +34,11 @@ set cpo-=C " BIND configuration file syn match namedComment "//.*" +syn match namedComment "#.*" syn region namedComment start="/\*" end="\*/" syn region namedString start=/"/ end=/"/ contained -" --- omitted trailing semicolon FIXME -syn match namedError /[^;{]$/ +" --- omitted trailing semicolon +syn match namedError /[^;{#]$/ " --- top-level keywords diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -1089,9 +1089,11 @@ GTK_MAN_TARGETS = yes GTK_TESTTARGET = gui ### Motif GUI -MOTIF_SRC = gui.c gui_motif.c gui_x11.c pty.c gui_beval.c +MOTIF_SRC = gui.c gui_motif.c gui_x11.c pty.c gui_beval.c \ + gui_xmdlg.c MOTIF_OBJ = objects/gui.o objects/gui_motif.o objects/gui_x11.o \ - objects/pty.o objects/gui_beval.o + objects/pty.o objects/gui_beval.o \ + objects/gui_xmdlg.o MOTIF_DEFS = -DFEAT_GUI_MOTIF $(NARROW_PROTO) MOTIF_IPATH = $(GUI_INC_LOC) MOTIF_LIBS_DIR = $(GUI_LIB_LOC) @@ -1203,8 +1205,8 @@ CARBONGUI_BUNDLE = $(VIMNAME).app CARBONGUI_TESTARG = VIMPROG=../$(CARBONGUI_BUNDLE)/Contents/MacOS/$(VIMTARGET) # All GUI files -ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_motif.c gui_athena.c gui_gtk_x11.c gui_x11.c gui_at_sb.c gui_at_fs.c pty.c gui_kde.cc gui_kde_wid.cc gui_kde_x11.cc gui_kde_wid_moc.cc -ALL_GUI_PRO = gui.pro gui_gtk.pro gui_motif.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w16.pro gui_w32.pro gui_amiga.pro gui_photon.pro +ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_motif.c gui_xmdlg.c gui_athena.c gui_gtk_x11.c gui_x11.c gui_at_sb.c gui_at_fs.c pty.c gui_kde.cc gui_kde_wid.cc gui_kde_x11.cc gui_kde_wid_moc.cc +ALL_GUI_PRO = gui.pro gui_gtk.pro gui_motif.pro gui_xmdlg.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w16.pro gui_w32.pro gui_amiga.pro gui_photon.pro # }}} @@ -2194,6 +2196,9 @@ objects/gui_gtk_x11.o: gui_gtk_x11.c objects/gui_motif.o: gui_motif.c $(CCC) -o $@ gui_motif.c +objects/gui_xmdlg.o: gui_xmdlg.c + $(CCC) -o $@ gui_xmdlg.c + objects/gui_x11.o: gui_x11.c $(CCC) -o $@ gui_x11.c diff --git a/src/gui_amiga.c b/src/gui_amiga.c --- a/src/gui_amiga.c +++ b/src/gui_amiga.c @@ -1238,6 +1238,7 @@ gui_mch_get_font(char_u *name, int giveE return NULL; } +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. * We always use the default font. @@ -1247,6 +1248,7 @@ gui_mch_get_fontname(GuiFont font, char_ { return vim_strsave((char_u *)"default"); } +#endif void gui_mch_set_font(GuiFont font) diff --git a/src/gui_beos.cc b/src/gui_beos.cc --- a/src/gui_beos.cc +++ b/src/gui_beos.cc @@ -2396,6 +2396,7 @@ error: return (GuiFont)font; } +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. */ @@ -2404,6 +2405,7 @@ gui_mch_get_fontname(GuiFont font, char_ { return vim_strsave(((VimFont *)font)->name); } +#endif /* * Set the current text font. diff --git a/src/gui_kde_x11.cc b/src/gui_kde_x11.cc --- a/src/gui_kde_x11.cc +++ b/src/gui_kde_x11.cc @@ -700,6 +700,7 @@ gui_mch_get_font(char_u * name, int repo return (GuiFont) myFont; }//}}} +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. * Don't know how to get the actual name, thus use the provided name. @@ -711,6 +712,7 @@ gui_mch_get_fontname(GuiFont font, char_ return NULL; return vim_strsave(name); }//}}} +#endif /* * Set the current text font. diff --git a/src/gui_mac.c b/src/gui_mac.c --- a/src/gui_mac.c +++ b/src/gui_mac.c @@ -3569,6 +3569,7 @@ gui_mch_get_font(name, giveErrorIfMissin return font; } +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. * Don't know how to get the actual name, thus use the provided name. @@ -3582,6 +3583,7 @@ gui_mch_get_fontname(font, name) return NULL; return vim_strsave(name); } +#endif /* * Set the current text font. diff --git a/src/gui_motif.c b/src/gui_motif.c --- a/src/gui_motif.c +++ b/src/gui_motif.c @@ -93,9 +93,6 @@ static void attachDump(Widget, char *); static void gui_motif_menu_colors __ARGS((Widget id)); static void gui_motif_scroll_colors __ARGS((Widget id)); -#ifdef FEAT_MENU -static void gui_motif_menu_fontlist __ARGS((Widget id)); -#endif #if (XmVersion >= 1002) # define STRING_TAG XmFONTLIST_DEFAULT_TAG @@ -125,17 +122,122 @@ scroll_cb(w, client_data, call_data) gui_drag_scrollbar(sb, value, dragging); } - /* * End of call-back routines */ +#ifndef LESSTIF_VERSION +/* + * Implement three dimensional shading of insensitive labels. + * By Martin Dalecki. + */ + +#include +#include + +static XtExposeProc old_label_expose = NULL; + +static void label_expose __ARGS((Widget _w, XEvent *_event, Region _region)); + + static void +label_expose(_w, _event, _region) + Widget _w; + XEvent *_event; + Region _region; +{ + GC insensitiveGC; + XmLabelWidget lw = (XmLabelWidget)_w; + unsigned char label_type = XmSTRING; + + XtVaGetValues(_w, XmNlabelType, &label_type, (XtPointer)0); + + if (XtIsSensitive(_w) || label_type != XmSTRING) + (*old_label_expose)(_w, _event, _region); + else + { + XGCValues values; + XtGCMask mask; + XtGCMask dynamic; + XFontStruct *fs; + + _XmFontListGetDefaultFont(lw->label.font, &fs); + + /* FIXME: we should be doing the whole drawing ourself here. */ + insensitiveGC = lw->label.insensitive_GC; + + mask = GCForeground | GCBackground | GCGraphicsExposures; + dynamic = GCClipMask | GCClipXOrigin | GCClipYOrigin; + values.graphics_exposures = False; + + if (fs != 0) + { + mask |= GCFont; + values.font = fs->fid; + } + + if (lw->primitive.top_shadow_pixmap != None + && lw->primitive.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP) + { + mask |= GCFillStyle | GCTile; + values.fill_style = FillTiled; + values.tile = lw->primitive.top_shadow_pixmap; + } + + lw->label.TextRect.x += 1; + lw->label.TextRect.y += 1; + if (lw->label._acc_text != 0) + { + lw->label.acc_TextRect.x += 1; + lw->label.acc_TextRect.y += 1; + } + + values.foreground = lw->primitive.top_shadow_color; + values.background = lw->core.background_pixel; + + lw->label.insensitive_GC = + XtAllocateGC((Widget) lw, 0, mask, &values, dynamic, 0); + (*old_label_expose)(_w, _event, _region); + XtReleaseGC(_w, lw->label.insensitive_GC); + + lw->label.TextRect.x -= 1; + lw->label.TextRect.y -= 1; + if (lw->label._acc_text != 0) + { + lw->label.acc_TextRect.x -= 1; + lw->label.acc_TextRect.y -= 1; + } + + values.foreground = lw->primitive.bottom_shadow_color; + values.background = lw->core.background_pixel; + + lw->label.insensitive_GC = + XtAllocateGC((Widget) lw, 0, mask, &values, dynamic, 0); + (*old_label_expose)(_w, _event, _region); + XtReleaseGC(_w, lw->label.insensitive_GC); + + lw->label.insensitive_GC = insensitiveGC; + } +} +#endif + + /* * Create all the motif widgets necessary. */ void gui_x11_create_widgets() { +#ifndef LESSTIF_VERSION + /* + * Install the 3D shade effect drawing routines. + */ + if (old_label_expose == NULL) + { + old_label_expose = xmLabelWidgetClass->core_class.expose; + xmLabelWidgetClass->core_class.expose = label_expose; + } +#endif + /* * Start out by adding the configured border width into the border offset */ @@ -329,9 +431,7 @@ gui_x11_set_back_color() * Manage dialog centered on pointer. This could be used by the Athena code as * well. */ -static void manage_centered __ARGS((Widget dialog_child)); - -static void + void manage_centered(dialog_child) Widget dialog_child; { @@ -855,16 +955,15 @@ gui_mch_add_menu_item(menu, idx) xms = XmStringCreate((char *)menu->dname, STRING_TAG); XtSetArg(args[n], XmNlabelString, xms); n++; -#ifndef FEAT_SUN_WORKSHOP - /* Without shadows one can't sense whatever the button has been * pressed or not! However we wan't to save a bit of space... + * Need the highlightThickness to see the focus. */ - XtSetArg(args[n], XmNhighlightThickness, 0); n++; + XtSetArg(args[n], XmNhighlightThickness, 1); n++; XtSetArg(args[n], XmNhighlightOnEnter, True); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; -#endif + if (menu->image == 0) { XtSetArg(args[n], XmNlabelType, XmSTRING); n++; @@ -1384,7 +1483,6 @@ gui_mch_create_scrollbar(sb, orient) int n; n = 0; - XtSetArg(args[n], XmNshadowThickness, 1); n++; XtSetArg(args[n], XmNminimum, 0); n++; XtSetArg(args[n], XmNorientation, (orient == SBAR_VERT) ? XmVERTICAL : XmHORIZONTAL); n++; @@ -1484,6 +1582,219 @@ gui_x11_get_wid() return(XtWindow(textArea)); } +/* + * Look for a widget in the widget tree w, with a mnemonic matching keycode. + * When one is found, simulate a button press on that widget and give it the + * keyboard focus. If the mnemonic is on a label, look in the userData field + * of the label to see if it points to another widget, and give that the focus. + */ + static void +do_mnemonic(Widget w, unsigned int keycode) +{ + WidgetList children; + int numChildren, i; + Boolean isMenu; + KeySym mnemonic = '\0'; + char mneString[2]; + Widget userData; + unsigned char rowColType; + + if (XtIsComposite(w)) + { + if (XtClass(w) == xmRowColumnWidgetClass) + { + XtVaGetValues(w, XmNrowColumnType, &rowColType, 0); + isMenu = (rowColType != (unsigned char)XmWORK_AREA); + } + else + isMenu = False; + if (!isMenu) + { + XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, + &numChildren, 0); + for (i = 0; i < numChildren; i++) + do_mnemonic(children[i], keycode); + } + } + else + { + XtVaGetValues(w, XmNmnemonic, &mnemonic, 0); + if (mnemonic != '\0') + { + mneString[0] = mnemonic; + mneString[1] = '\0'; + if (XKeysymToKeycode(XtDisplay(XtParent(w)), + XStringToKeysym(mneString)) == keycode) + { + if (XtClass(w) == xmLabelWidgetClass + || XtClass(w) == xmLabelGadgetClass) + { + XtVaGetValues(w, XmNuserData, &userData, 0); + if (userData != NULL && XtIsWidget(userData)) + XmProcessTraversal(userData, XmTRAVERSE_CURRENT); + } + else + { + XKeyPressedEvent keyEvent; + + XmProcessTraversal(w, XmTRAVERSE_CURRENT); + + memset((char *) &keyEvent, 0, sizeof(XKeyPressedEvent)); + keyEvent.type = KeyPress; + keyEvent.serial = 1; + keyEvent.send_event = True; + keyEvent.display = XtDisplay(w); + keyEvent.window = XtWindow(w); + XtCallActionProc(w, "Activate", (XEvent *) & keyEvent, + NULL, 0); + } + } + } + } +} + +/* + * Callback routine for dialog mnemonic processing. + */ +/*ARGSUSED*/ + static void +mnemonic_event(Widget w, XtPointer call_data, XKeyEvent *event) +{ + do_mnemonic(w, event->keycode); +} + + +/* + * Search the widget tree under w for widgets with mnemonics. When found, add + * a passive grab to the dialog widget for the mnemonic character, thus + * directing mnemonic events to the dialog widget. + */ + static void +add_mnemonic_grabs(Widget dialog, Widget w) +{ + char mneString[2]; + WidgetList children; + int numChildren, i; + Boolean isMenu; + KeySym mnemonic = '\0'; + unsigned char rowColType; + + if (XtIsComposite(w)) + { + if (XtClass(w) == xmRowColumnWidgetClass) + { + XtVaGetValues(w, XmNrowColumnType, &rowColType, 0); + isMenu = (rowColType != (unsigned char)XmWORK_AREA); + } + else + isMenu = False; + if (!isMenu) + { + XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, + &numChildren, 0); + for (i = 0; i < numChildren; i++) + add_mnemonic_grabs(dialog, children[i]); + } + } + else + { + XtVaGetValues(w, XmNmnemonic, &mnemonic, 0); + if (mnemonic != '\0') + { + mneString[0] = mnemonic; + mneString[1] = '\0'; + XtGrabKey(dialog, XKeysymToKeycode(XtDisplay(dialog), + XStringToKeysym(mneString)), + Mod1Mask, True, GrabModeAsync, GrabModeAsync); + } + } +} + +/* + * Add a handler for mnemonics in a dialog. Motif itself only handles + * mnemonics in menus. Mnemonics added or changed after this call will be + * ignored. + * + * To add a mnemonic to a text field or list, set the XmNmnemonic resource on + * the appropriate label and set the XmNuserData resource of the label to the + * widget to get the focus when the mnemonic is typed. + */ + static void +activate_dialog_mnemonics(Widget dialog) +{ + if (!dialog) + return; + + XtAddEventHandler(dialog, KeyPressMask, False, + (XtEventHandler) mnemonic_event, (XtPointer) NULL); + add_mnemonic_grabs(dialog, dialog); +} + +/* + * Removes the event handler and key-grabs for dialog mnemonic handling. + */ + static void +suppress_dialog_mnemonics(Widget dialog) +{ + if (!dialog) + return; + + XtUngrabKey(dialog, AnyKey, Mod1Mask); + XtRemoveEventHandler(dialog, KeyPressMask, False, + (XtEventHandler) mnemonic_event, (XtPointer) NULL); +} + +#if defined(FEAT_BROWSE) || defined(FEAT_GUI_DIALOG) +static void set_fontlist __ARGS((Widget wg)); + +/* + * Use the 'guifont' or 'guifontset' as a fontlist for a dialog widget. + */ + static void +set_fontlist(id) + Widget id; +{ + XmFontList fl; + +#ifdef FONTSET_ALWAYS + if (gui.fontset != NOFONTSET) { + fl = gui_motif_fontset2fontlist((XFontSet *)&gui.fontset); + if (fl != NULL) + { + if (XtIsManaged(id)) + { + XtUnmanageChild(id); + XtVaSetValues(id, XmNfontList, fl, NULL); + /* We should force the widget to recalculate it's + * geometry now. */ + XtManageChild(id); + } + else + XtVaSetValues(id, XmNfontList, fl, NULL); + XmFontListFree(fl); + } + } +#else + if (gui.norm_font != NOFONT) { + fl = gui_motif_create_fontlist((XFontStruct *)gui.norm_font); + if (fl != NULL) + { + if (XtIsManaged(id)) + { + XtUnmanageChild(id); + XtVaSetValues(id, XmNfontList, fl, NULL); + /* We should force the widget to recalculate it's + * geometry now. */ + XtManageChild(id); + } + else + XtVaSetValues(id, XmNfontList, fl, NULL); + XmFontListFree(fl); + } + } +#endif +} +#endif #if defined(FEAT_BROWSE) || defined(PROTO) @@ -1517,29 +1828,67 @@ static void DialogAcceptCB __ARGS((Widge * - equalize the messages between different GUI implementations as far as * possible. */ -static void set_predefined_label __ARGS((Widget parent, String name, char * new_label)); +static void set_predefined_label __ARGS((Widget parent, String name, char *new_label)); static void set_predefined_label(parent, name, new_label) - Widget parent; - String name; - char * new_label; + Widget parent; + String name; + char *new_label; { - XmString str; - Widget w; + XmString str; + Widget w; + char_u *p, *next; + KeySym mnemonic = NUL; w = XtNameToWidget(parent, name); if (!w) return; - str = XmStringCreate(new_label, STRING_TAG); - - if (str) + p = vim_strsave((char_u *)new_label); + if (p == NULL) + return; + for (next = p; *next; ++next) { - XtVaSetValues(w, XmNlabelString, str, NULL); + if (*next == DLG_HOTKEY_CHAR) + { + int len = STRLEN(next); + + if (len > 0) + { + mch_memmove(next, next + 1, len); + mnemonic = next[0]; + } + } + } + + str = XmStringCreate((char *)p, STRING_TAG); + vim_free(p); + + if (str != NULL) + { + XtVaSetValues(w, + XmNlabelString, str, + XmNmnemonic, mnemonic, + NULL); XmStringFree(str); } + gui_motif_menu_fontlist(w); +} + +static void +set_predefined_fontlist(parent, name) + Widget parent; + String name; +{ + Widget w; + w = XtNameToWidget(parent, name); + + if (!w) + return; + + set_fontlist(w); } /* @@ -1561,7 +1910,12 @@ gui_mch_browse(saving, title, dflt, ext, char_u *pattern; char_u *tofree = NULL; - dialog_wgt = XmCreateFileSelectionDialog(vimShell, (char *)title, NULL, 0); + /* There a difference between the resource name and value, Therefore, we + * avoid to (ab-)use the (maybe internationalized!) dialog title as a + * dialog name. + */ + + dialog_wgt = XmCreateFileSelectionDialog(vimShell, "browseDialog", NULL, 0); if (initdir == NULL || *initdir == NUL) { @@ -1614,15 +1968,21 @@ gui_mch_browse(saving, title, dflt, ext, XmNdialogTitle, XmRString, (char *)title, STRLEN(title) + 1, NULL); - set_predefined_label(dialog_wgt, "Apply", _("Filter")); - set_predefined_label(dialog_wgt, "Cancel", _("Cancel")); + set_predefined_label(dialog_wgt, "Apply", _("&Filter")); + set_predefined_label(dialog_wgt, "Cancel", _("&Cancel")); set_predefined_label(dialog_wgt, "Dir", _("Directories")); set_predefined_label(dialog_wgt, "FilterLabel", _("Filter")); - set_predefined_label(dialog_wgt, "Help", _("Help")); + set_predefined_label(dialog_wgt, "Help", _("&Help")); set_predefined_label(dialog_wgt, "Items", _("Files")); - set_predefined_label(dialog_wgt, "OK", _("OK")); + set_predefined_label(dialog_wgt, "OK", _("&OK")); set_predefined_label(dialog_wgt, "Selection", _("Selection")); + /* This is to save us from silly external settings using not fixed with + * fonts for file selection. + */ + set_predefined_fontlist(dialog_wgt, "DirListSW.DirList"); + set_predefined_fontlist(dialog_wgt, "ItemsListSW.ItemsList"); + gui_motif_menu_colors(dialog_wgt); if (gui.scroll_bg_pixel != INVALCOLOR) XtVaSetValues(dialog_wgt, XmNtroughColor, gui.scroll_bg_pixel, NULL); @@ -1634,6 +1994,7 @@ gui_mch_browse(saving, title, dflt, ext, (unsigned char)XmDIALOG_HELP_BUTTON)); manage_centered(dialog_wgt); + activate_dialog_mnemonics(dialog_wgt); /* sit in a loop until the dialog box has gone away */ do @@ -1642,6 +2003,7 @@ gui_mch_browse(saving, title, dflt, ext, (XtInputMask)XtIMAll); } while (XtIsManaged(dialog_wgt)); + suppress_dialog_mnemonics(dialog_wgt); XtDestroyWidget(dialog_wgt); vim_free(tofree); @@ -1746,31 +2108,6 @@ butproc(w, client_data, call_data) dialogStatus = (int)(long)client_data + 1; } -static void gui_motif_set_fontlist __ARGS((Widget wg)); - -/* - * Use the 'guifont' or 'guifontset' as a fontlist for a dialog widget. - */ - static void -gui_motif_set_fontlist(wg) - Widget wg; -{ - XmFontList fl; - - fl = -#ifdef FEAT_XFONTSET - gui.fontset != NOFONTSET ? - gui_motif_fontset2fontlist((XFontSet *)&gui.fontset) - : -#endif - gui_motif_create_fontlist((XFontStruct *)gui.norm_font); - if (fl != NULL) - { - XtVaSetValues(wg, XmNfontList, fl, NULL); - XmFontListFree(fl); - } -} - #ifdef HAVE_XPM static Widget create_pixmap_label(Widget parent, String name, char **data, ArgList args, Cardinal arg); @@ -1853,6 +2190,7 @@ gui_mch_dialog(type, title, message, but XtAppContext app; XmString label; int butcount; + Widget w; Widget dialogform = NULL; Widget form = NULL; Widget dialogtextfield = NULL; @@ -1913,10 +2251,20 @@ gui_mch_dialog(type, title, message, but p = buts; for (butcount = 0; *p; ++butcount) { + KeySym mnemonic = NUL; + for (next = p; *next; ++next) { if (*next == DLG_HOTKEY_CHAR) - mch_memmove(next, next + 1, STRLEN(next)); + { + int len = STRLEN(next); + + if (len > 0) + { + mch_memmove(next, next + 1, len); + mnemonic = next[0]; + } + } if (*next == DLG_BUTTON_SEP) { *next++ = NUL; @@ -1930,12 +2278,14 @@ gui_mch_dialog(type, title, message, but buttons[butcount] = XtVaCreateManagedWidget("button", xmPushButtonWidgetClass, dialogform, XmNlabelString, label, + XmNmnemonic, mnemonic, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 4, XmNshowAsDefault, butcount == dfltbutton - 1, XmNdefaultButtonShadowThickness, 1, NULL); XmStringFree(label); + gui_motif_menu_fontlist(buttons[butcount]); /* Layout properly. */ @@ -2041,7 +2391,7 @@ gui_mch_dialog(type, title, message, but XmNbottomAttachment, XmATTACH_FORM, NULL); - gui_motif_set_fontlist(dialogtextfield); + set_fontlist(dialogtextfield); XmTextFieldSetString(dialogtextfield, (char *)textfield); XtManageChild(dialogtextfield); XtAddEventHandler(dialogtextfield, KeyPressMask, False, @@ -2093,13 +2443,19 @@ gui_mch_dialog(type, title, message, but XtManageChild(dialogpixmap); #endif - /* Create the dialog message. */ - label = XmStringLtoRCreate((char *)message, STRING_TAG); + /* Create the dialog message. + * Since LessTif is apparently having problems with the creation of + * properly localized string, we use LtoR here. The symptom is that the + * string sill not show properly in multiple lines as it does in native + * Motif. + */ + label = XmStringCreateLtoR((char *)message, STRING_TAG); if (label == NULL) return -1; - (void)XtVaCreateManagedWidget("dialogMessage", + w = XtVaCreateManagedWidget("dialogMessage", xmLabelGadgetClass, form, XmNlabelString, label, + XmNalignment, XmALIGNMENT_BEGINNING, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 8, #ifdef HAVE_XPM @@ -2115,6 +2471,7 @@ gui_mch_dialog(type, title, message, but XmNbottomOffset, 8, NULL); XmStringFree(label); + set_fontlist(w); if (textfield != NULL) { @@ -2149,6 +2506,7 @@ gui_mch_dialog(type, title, message, but NULL); manage_centered(dialogform); + activate_dialog_mnemonics(dialogform); if (textfield != NULL && *textfield != NUL) { @@ -2185,6 +2543,7 @@ gui_mch_dialog(type, title, message, but } } + suppress_dialog_mnemonics(dialogform); XtDestroyWidget(dialogform); return dialogStatus; @@ -2246,8 +2605,11 @@ gui_mch_set_footer(s) XmString xms; xms = XmStringCreate((char *)s, STRING_TAG); - XtVaSetValues(footer, XmNlabelString, xms, NULL); - XmStringFree(xms); + if (xms != NULL) + { + XtVaSetValues(footer, XmNlabelString, xms, NULL); + XmStringFree(xms); + } } #endif @@ -2522,14 +2884,15 @@ gui_motif_scroll_colors(id) XtVaSetValues(id, XmNforeground, gui.scroll_fg_pixel, NULL); } -#ifdef FEAT_MENU /* * Set the fontlist for Widget "id" to use gui.menu_fontset or gui.menu_font. */ - static void +/*ARGSUSED*/ + void gui_motif_menu_fontlist(id) Widget id; { +#ifdef FEAT_MENU #ifdef FONTSET_ALWAYS if (gui.menu_fontset != NOFONTSET) { @@ -2573,9 +2936,9 @@ gui_motif_menu_fontlist(id) } } #endif +#endif } -#endif /* * We don't create it twice for the sake of speed. @@ -2617,8 +2980,10 @@ find_replace_destroy_callback(w, client_ { SharedFindReplace *cd = (SharedFindReplace *)client_data; - if (cd != NULL) + if (cd != NULL) { + /* suppress_dialog_mnemonics(cd->dialog); */ cd->dialog = (Widget)0; + } } /*ARGSUSED*/ @@ -2719,6 +3084,48 @@ find_replace_keypress(w, frdp, event) } static void +set_label(w, label) + Widget w; + char_u *label; +{ + XmString str; + char_u *p, *next; + KeySym mnemonic = NUL; + + if (!w) + return; + + p = vim_strsave(label); + if (p == NULL) + return; + for (next = p; *next; ++next) + { + if (*next == DLG_HOTKEY_CHAR) + { + int len = STRLEN(next); + + if (len > 0) + { + mch_memmove(next, next + 1, len); + mnemonic = next[0]; + } + } + } + + str = XmStringCreateSimple((char *)p); + vim_free(p); + if (str) + { + XtVaSetValues(w, + XmNlabelString, str, + XmNmnemonic, mnemonic, + NULL); + XmStringFree(str); + } + gui_motif_menu_fontlist(w); +} + + static void find_replace_dialog_create(arg, do_replace) char_u *arg; int do_replace; @@ -2746,6 +3153,8 @@ find_replace_dialog_create(arg, do_repla /* If the dialog already exists, just raise it. */ if (frdp->dialog) { + gui_motif_synch_fonts(); + /* If the window is already up, just pop it to the top */ if (XtIsManaged(frdp->dialog)) XMapRaised(XtDisplay(frdp->dialog), @@ -2789,16 +3198,14 @@ find_replace_dialog_create(arg, do_repla XmNbottomOffset, 4, NULL); - str = XmStringCreateSimple(_("Find Next")); frdp->find = XtVaCreateManagedWidget("findButton", xmPushButtonWidgetClass, button_form, - XmNlabelString, str, XmNsensitive, True, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); - XmStringFree(str); + set_label(frdp->find, _("Find &Next")); XtAddCallback(frdp->find, XmNactivateCallback, find_replace_callback, @@ -2806,57 +3213,50 @@ find_replace_dialog_create(arg, do_repla if (do_replace) { - str = XmStringCreateSimple(_("Replace")); frdp->replace = XtVaCreateManagedWidget("replaceButton", xmPushButtonWidgetClass, button_form, - XmNlabelString, str, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frdp->find, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); - XmStringFree(str); + set_label(frdp->replace, _("&Replace")); XtAddCallback(frdp->replace, XmNactivateCallback, find_replace_callback, (XtPointer)FRD_REPLACE); - str = XmStringCreateSimple(_("Replace All")); frdp->all = XtVaCreateManagedWidget("replaceAllButton", xmPushButtonWidgetClass, button_form, - XmNlabelString, str, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frdp->replace, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); - XmStringFree(str); + set_label(frdp->all, _("Replace &All")); XtAddCallback(frdp->all, XmNactivateCallback, find_replace_callback, (XtPointer)FRD_REPLACEALL); - str = XmStringCreateSimple(_("Undo")); frdp->undo = XtVaCreateManagedWidget("undoButton", xmPushButtonWidgetClass, button_form, - XmNlabelString, str, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frdp->all, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); - XmStringFree(str); + set_label(frdp->undo, _("&Undo")); XtAddCallback(frdp->undo, XmNactivateCallback, find_replace_callback, (XtPointer)FRD_UNDO); } - str = XmStringCreateSimple(_("Cancel")); frdp->cancel = XtVaCreateManagedWidget("closeButton", xmPushButtonWidgetClass, button_form, - XmNlabelString, str, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL); - XmStringFree(str); + set_label(frdp->cancel, _("&Cancel")); XtAddCallback(frdp->cancel, XmNactivateCallback, find_replace_dismiss_callback, frdp); + gui_motif_menu_fontlist(frdp->cancel); XtManageChild(button_form); @@ -2894,6 +3294,7 @@ find_replace_dialog_create(arg, do_repla XmNtopOffset, 4, NULL); XmStringFree(str); + gui_motif_menu_fontlist(label_what); frdp->what = XtVaCreateManagedWidget("whatText", xmTextFieldWidgetClass, input_form, @@ -2928,6 +3329,7 @@ find_replace_dialog_create(arg, do_repla XmNbottomAttachment, XmATTACH_FORM, NULL); XmStringFree(str); + gui_motif_menu_fontlist(label_with); /* * Make the entry activation only change the input focus onto the @@ -2975,6 +3377,7 @@ find_replace_dialog_create(arg, do_repla { Widget radio_box; + Widget w; frame = XtVaCreateWidget("directionFrame", xmFrameWidgetClass, frdp->dialog, @@ -2988,13 +3391,14 @@ find_replace_dialog_create(arg, do_repla NULL); str = XmStringCreateSimple(_("Direction")); - (void)XtVaCreateManagedWidget("directionFrameLabel", + w = XtVaCreateManagedWidget("directionFrameLabel", xmLabelGadgetClass, frame, XmNlabelString, str, XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, XmNchildType, XmFRAME_TITLE_CHILD, NULL); XmStringFree(str); + gui_motif_menu_fontlist(w); radio_box = XmCreateRadioBox(frame, "radioBox", (ArgList)NULL, 0); @@ -3006,6 +3410,7 @@ find_replace_dialog_create(arg, do_repla XmNset, False, NULL); XmStringFree(str); + gui_motif_menu_fontlist(frdp->up); str = XmStringCreateSimple(_("Down")); frdp->down = XtVaCreateManagedWidget("downRadioButton", @@ -3014,6 +3419,7 @@ find_replace_dialog_create(arg, do_repla XmNset, True, NULL); XmStringFree(str); + gui_motif_menu_fontlist(frdp->down); XtManageChild(radio_box); XtManageChild(frame); @@ -3057,6 +3463,8 @@ find_replace_dialog_create(arg, do_repla XmNset, mcase, NULL); XmStringFree(str); + gui_motif_menu_fontlist(frdp->wword); + gui_motif_menu_fontlist(frdp->mcase); XtManageChild(toggle_form); @@ -3064,7 +3472,10 @@ find_replace_dialog_create(arg, do_repla XmTextFieldSetString(frdp->what, (char *)entry_text); vim_free(entry_text); - XtManageChild(frdp->dialog); + gui_motif_synch_fonts(); + + manage_centered(frdp->dialog); + activate_dialog_mnemonics(frdp->dialog); XmProcessTraversal(frdp->what, XmTRAVERSE_CURRENT); } @@ -3088,3 +3499,40 @@ gui_mch_replace_dialog(eap) find_replace_dialog_create(eap->arg, TRUE); } + +/* + * Synchronize all gui elements, which are dependant upon the + * main text font used. Those are in esp. the find/replace dialogs. + * If you don't understand why this should be needed, please try to + * search for "pięść" in iso8859-2. + */ + void +gui_motif_synch_fonts(void) +{ + SharedFindReplace *frdp; + int do_replace; + XFontStruct *font; + XmFontList font_list; + + /* FIXME: Unless we find out how to create a XmFontList from a XFontSet, + * we just give up here on font synchronization. */ + font = (XFontStruct *)gui.norm_font; + if (font == NULL) + return; + + font_list = gui_motif_create_fontlist(font); + + /* OK this loop is a bit tricky... */ + for (do_replace = 0; do_replace <= 1; ++do_replace) + { + frdp = (do_replace) ? (&repl_widgets) : (&find_widgets); + if (frdp->dialog) + { + XtVaSetValues(frdp->what, XmNfontList, font_list, NULL); + if (do_replace) + XtVaSetValues(frdp->with, XmNfontList, font_list, NULL); + } + } + + XmFontListFree(font_list); +} diff --git a/src/gui_photon.c b/src/gui_photon.c --- a/src/gui_photon.c +++ b/src/gui_photon.c @@ -3047,6 +3047,7 @@ gui_mch_get_font(char_u *vim_font_name, return( FAIL ); } +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. * Don't know how to get the actual name, thus use the provided name. @@ -3060,6 +3061,7 @@ gui_mch_get_fontname(font, name) return NULL; return vim_strsave(name); } +#endif void gui_mch_set_font(GuiFont font) diff --git a/src/gui_riscos.c b/src/gui_riscos.c --- a/src/gui_riscos.c +++ b/src/gui_riscos.c @@ -1052,6 +1052,7 @@ gui_mch_get_font(name, giveErrorIfMissin return handle; } +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. * Don't know how to get the actual name, thus use the provided name. @@ -1065,6 +1066,7 @@ gui_mch_get_fontname(font, name) return NULL; return vim_strsave(name); } +#endif /* * Set the current text font. diff --git a/src/gui_w48.c b/src/gui_w48.c --- a/src/gui_w48.c +++ b/src/gui_w48.c @@ -1249,6 +1249,7 @@ gui_mch_get_font( return font; } +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. * Don't know how to get the actual name, thus use the provided name. @@ -1262,6 +1263,7 @@ gui_mch_get_fontname(font, name) return NULL; return vim_strsave(name); } +#endif void gui_mch_free_font(GuiFont font) diff --git a/src/gui_xmdlg.c b/src/gui_xmdlg.c new file mode 100644 --- /dev/null +++ b/src/gui_xmdlg.c @@ -0,0 +1,1287 @@ +/* vi:set ts=8 sts=4 sw=4: + * + * VIM - Vi IMproved by Bram Moolenaar + * GUI/Motif support by Robert Webb + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * (C) 2001 by Marcin Dalecki + * + * Implementation of dialogue functions for the Motif GUI variant. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "vim.h" + +extern Widget vimShell; + +#ifdef FEAT_MENU +# define apply_fontlist(w) gui_motif_menu_fontlist(w) +#else +# define apply_fontlist(w) +#endif + +/**************************************************************************** + * Font selection dialogue implementation. + */ + +static char wild[3] = "*"; + +/* + * FIXME: This is a generic function, which should be used throughout the whole + * application. + * + * Add close_callback, which will be called when the user selects close from + * the window menu. The close menu item usually activates f.kill which sends a + * WM_DELETE_WINDOW protocol request for the window. + */ + + static void +add_cancel_action(Widget shell, XtCallbackProc close_callback, void *arg) +{ + static Atom wmp_atom = 0; + static Atom dw_atom = 0; + Display *display = XtDisplay(shell); + + /* deactivate the built-in delete response of killing the application */ + XtVaSetValues(shell, XmNdeleteResponse, XmDO_NOTHING, 0); + + /* add a delete window protocol callback instead */ + if (!dw_atom) + { + wmp_atom = XmInternAtom(display, "WM_PROTOCOLS", True); + dw_atom = XmInternAtom(display, "WM_DELETE_WINDOW", True); + } + XmAddProtocolCallback(shell, wmp_atom, dw_atom, close_callback, arg); +} + +#define MAX_FONTS 65535 +#define MAX_FONT_NAME_LEN 256 +#define MAX_ENTRIES_IN_LIST 5000 +#define MAX_DISPLAY_SIZE 150 +#define TEMP_BUF_SIZE 256 + +enum ListSpecifier +{ + ENCODING, + NAME, + STYLE, + SIZE, + NONE +}; + +typedef struct _SharedFontSelData +{ + Widget dialog; + Widget ok; + Widget cancel; + Widget encoding_pulldown; + Widget encoding_menu; + Widget list[NONE]; + Widget name; + Widget sample; + char **names; /* font name array of arrays */ + int num; /* number of font names */ + String sel[NONE]; /* selection category */ + Boolean in_pixels; /* toggle state - size in pixels */ + char *font_name; /* current font name */ + XFontStruct *old; /* font data structure for sample display */ + XmFontList old_list; /* font data structure for sample display */ + Boolean exit; /* used for program exit control */ +} SharedFontSelData; + +/* + * Checking access to the font name array for validity. + */ + static char * +fn(SharedFontSelData *data, int i) +{ + /* Assertion checks: */ + if (data->num < 0) + abort(); + if (i >= data->num) + i = data->num - 1; + if (i < 0) + i = 0; + + return data->names[i]; +} + +/* + * Get a specific substring from a font name. + */ + static void +get_part(char *in, int pos, char *out) +{ + int i; + int j; + + *out = '\0'; + + for (i = 0; (pos > 0) && (in[i] != '\0'); ++i) + if (in[i] == '-') + pos--; + + if (in[i] == '\0') + return; + + for (j = 0; (in[i] != '-') && (in[i] != '\0'); ++i, ++j) + out[j] = in[i]; + out[j] = '\0'; +} + +/* + * Given a font name this function returns the part used in the first + * scroll list. + */ + static void +name_part(char *font, char *buf) +{ + char buf2[TEMP_BUF_SIZE]; + char buf3[TEMP_BUF_SIZE]; + + get_part(font, 2, buf2); + get_part(font, 1, buf3); + + if (strlen(buf3)) + sprintf(buf, "%s (%s)", buf2, buf3); + else + sprintf(buf, "%s", buf2); +} + +/* + * Given a font name this function returns the part used in the second scroll list. + */ + static void +style_part(char *font, char *buf) +{ + char buf2[TEMP_BUF_SIZE]; + char buf3[TEMP_BUF_SIZE]; + + get_part(font, 3, buf3); + get_part(font, 5, buf2); + + if (!strcmp(buf2, "normal") && !strcmp(buf2, "Normal") + && !strcmp(buf2, "NORMAL")) + sprintf(buf, "%s %s", buf3, buf2); + else + strcpy(buf, buf3); + + get_part(font, 6, buf2); + + if (buf2[0] != '\0') + sprintf(buf3, "%s %s", buf, buf2); + else + strcpy(buf3, buf); + + get_part(font, 4, buf2); + + if (!strcmp(buf2, "o") || !strcmp(buf2, "O")) + sprintf(buf, "%s oblique", buf3); + else if (!strcmp(buf2, "i") || !strcmp(buf2, "I")) + sprintf(buf, "%s italic", buf3); + + if (!strcmp(buf, " ")) + strcpy(buf, "-"); +} + +/* + * Given a font name this function returns the part used in the third + * scroll list. + */ + static void +size_part(char *font, char *buf, int inPixels) +{ + int size; + float temp; + + *buf = '\0'; + + if (inPixels) + { + get_part(font, 7, buf); + if (strlen(buf) > 0) + { + size = atoi(buf); + sprintf(buf, "%3d", size); + } + } + else + { + get_part(font, 8, buf); + if (strlen(buf) > 0) + { + size = atoi(buf); + temp = (float)size / 10.0; + size = temp; + if (buf[strlen(buf) - 1] == '0') + sprintf(buf, "%3d", size); + else + sprintf(buf, "%4.1f", temp); + } + } +} + +/* + * Given a font name this function returns the part used in the choice menu. + */ + static void +encoding_part(char *font, char *buf) +{ + char buf1[TEMP_BUF_SIZE]; + char buf2[TEMP_BUF_SIZE]; + + *buf = '\0'; + + get_part(font, 13, buf1); + get_part(font, 14, buf2); + + if (strlen(buf1) > 0 && strlen(buf2)) + sprintf(buf, "%s-%s", buf1, buf2); + if (!strcmp(buf, " ")) + strcpy(buf, "-"); +} + +/* + * Inserts a string into correct sorted position in a list. + */ + static void +add_to_list(char **buf, char *item, int *count) +{ + int i; + int j; + + if (*count == MAX_ENTRIES_IN_LIST) + return; + + /* avoid duplication */ + for (i = 0; i < *count; ++i) + { + if (!strcmp(buf[i], item)) + return; + } + + /* find order place, but make sure that wild card comes first */ + if (!strcmp(item, wild)) + i = 0; + else + for (i = 0; i < *count; ++i) + if (strcmp(buf[i], item) > 0 && strcmp(buf[i], wild)) + break; + + /* now insert the item */ + for (j = *count; j > i; --j) + buf[j] = buf[j-1]; + buf[i] = XtNewString(item); + + ++(*count); +} + +/* + * True if the font matches some field. + */ + static Boolean +match(SharedFontSelData *data, enum ListSpecifier l, int i) +{ + char buf[TEMP_BUF_SIZE]; + + /* An empty selection or a wild card matches anything. + */ + if (!data->sel[l] || !strcmp(data->sel[l], wild)) + return True; + + /* chunk out the desired part... */ + switch (l) + { + case ENCODING: + encoding_part(fn(data, i), buf); + break; + + case NAME: + name_part(fn(data, i), buf); + break; + + case STYLE: + style_part(fn(data, i), buf); + break; + + case SIZE: + size_part(fn(data, i), buf, data->in_pixels); + break; + default: + ; + } + + /* ...and chew it now */ + + return !strcmp(buf, data->sel[l]); +} + + static Boolean +proportional(char *font) +{ + char buf[TEMP_BUF_SIZE]; + + get_part(font, 11, buf); + + return !strcmp(buf, "p") || !strcmp(buf, "P"); +} + + +static void encoding_callback(Widget w, SharedFontSelData *data, + XtPointer dummy); + +/* + * Parse through the fontlist data and set up the three scroll lists. The fix + * parameter can be used to exclude a list from any changes. This is used for + * updates after selections caused by the users actions. + */ + static void +fill_lists(enum ListSpecifier fix, SharedFontSelData *data) +{ + char *list[NONE][MAX_ENTRIES_IN_LIST]; + int count[NONE]; + char buf[TEMP_BUF_SIZE]; + XmString items[MAX_ENTRIES_IN_LIST]; + int i; + int index; + + for (index = (int)ENCODING; index < (int)NONE; ++index) + count[index] = 0; + + /* First we insert the wild char into every single list. */ + if (fix != ENCODING) + add_to_list(list[ENCODING], wild, &count[ENCODING]); + if (fix != NAME) + add_to_list(list[NAME], wild, &count[NAME]); + if (fix != STYLE) + add_to_list(list[STYLE], wild, &count[STYLE]); + if (fix != SIZE) + add_to_list(list[SIZE], wild, &count[SIZE]); + + for (i = 0; i < data->num && i < MAX_ENTRIES_IN_LIST; i++) + { + if (proportional(fn(data, i))) + continue; + + if (fix != ENCODING + && match(data, NAME, i) + && match(data, STYLE, i) + && match(data, SIZE, i)) + { + encoding_part(fn(data, i), buf); + add_to_list(list[ENCODING], buf, &count[ENCODING]); + } + + if (fix != NAME + && match(data, ENCODING, i) + && match(data, STYLE, i) + && match(data, SIZE, i)) + { + name_part(fn(data, i), buf); + add_to_list(list[NAME], buf, &count[NAME]); + } + + if (fix != STYLE + && match(data, ENCODING, i) + && match(data, NAME, i) + && match(data, SIZE, i)) + { + style_part(fn(data, i), buf); + add_to_list(list[STYLE], buf, &count[STYLE]); + } + + if (fix != SIZE + && match(data, ENCODING, i) + && match(data, NAME, i) + && match(data, STYLE, i)) + { + size_part(fn(data, i), buf, data->in_pixels); + add_to_list(list[SIZE], buf, &count[SIZE]); + } + } + + /* + * And now do the preselection in all lists where there was one: + */ + + if (fix != ENCODING) + { + Cardinal n_items; + WidgetList children; + Widget selected_button = 0; + + /* Get and update the current button list. */ + XtVaGetValues(data->encoding_pulldown, + XmNchildren, &children, + XmNnumChildren, &n_items, + NULL); + + for (i = 0; i < count[ENCODING]; ++i) + { + Widget button; + + items[i] = XmStringCreateLocalized(list[ENCODING][i]); + + if (i < n_items) + { + /* recycle old button */ + XtVaSetValues(children[i], + XmNlabelString, items[i], + XmNuserData, i, + NULL); + button = children[i]; + } + else + { + /* create a new button */ + button = XtVaCreateManagedWidget("button", + xmPushButtonGadgetClass, + data->encoding_pulldown, + XmNlabelString, items[i], + XmNuserData, i, + NULL); + XtAddCallback(button, XmNactivateCallback, + (XtCallbackProc) encoding_callback, (XtPointer) data); + XtManageChild(button); + } + + if (data->sel[ENCODING]) + { + if (!strcmp(data->sel[ENCODING], list[ENCODING][i])) + selected_button = button; + } + XtFree(list[ENCODING][i]); + } + + /* Destroy all the outstandig menu items. + */ + for (i = count[ENCODING]; i < n_items; ++i) + { + XtUnmanageChild(children[i]); + XtDestroyWidget(children[i]); + } + + /* Preserve the current selection visually. + */ + if (selected_button) + { + XtVaSetValues(data->encoding_menu, + XmNmenuHistory, selected_button, + NULL); + } + + for (i = 0; i < count[ENCODING]; ++i) + XmStringFree(items[i]); + } + + /* + * Now loop trough the remaining lists and set them up. + */ + for (index = (int)NAME; index < (int)NONE; ++index) + { + Widget w; + + if (fix == (enum ListSpecifier)index) + continue; + + switch ((enum ListSpecifier)index) + { + case NAME: + w = data->list[NAME]; + break; + case STYLE: + w = data->list[STYLE]; + break; + case SIZE: + w = data->list[SIZE]; + break; + default: + w = (Widget)0; /* for lint */ + } + + for (i = 0; i < count[index]; ++i) + { + items[i] = XmStringCreateLocalized(list[index][i]); + XtFree(list[index][i]); + } + XmListDeleteAllItems(w); + XmListAddItems(w, items, count[index], 1); + if (data->sel[index]) + { + XmStringFree(items[0]); + items[0] = XmStringCreateLocalized(data->sel[index]); + XmListSelectItem(w, items[0], False); + XmListSetBottomItem(w, items[0]); + } + for (i = 0; i < count[index]; ++i) + XmStringFree(items[i]); + } +} + +/*ARGSUSED*/ + static void +stoggle_callback(Widget w, + SharedFontSelData *data, + XmToggleButtonCallbackStruct *call_data) +{ + int i, do_sel; + char newSize[10]; + XmString str; + + if (call_data->reason != (int)XmCR_VALUE_CHANGED) + return; + + do_sel = (data->sel[SIZE] != NULL) && strcmp(data->sel[SIZE], wild); + + for (i = 0; do_sel && (i < data->num); i++) + if (match(data, ENCODING, i) + && match(data, NAME, i) + && match(data, STYLE, i) + && match(data, SIZE, i)) + { + size_part(fn(data, i), newSize, !data->in_pixels); + break; + } + + data->in_pixels = !data->in_pixels; + + if (data->sel[SIZE]) + XtFree(data->sel[SIZE]); + data->sel[SIZE] = NULL; + fill_lists(NONE, data); + + if (do_sel) + { + str = XmStringCreateLocalized(newSize); + XmListSelectItem(data->list[SIZE], str, True); + XmListSetBottomItem(data->list[SIZE], str); + XmStringFree(str); + } +} + +/* + * Show the currently selected font in the sample text label. + */ + static void +display_sample(SharedFontSelData *data) +{ + Arg args[2]; + int n; + XFontStruct * font; + XmFontList font_list; + Display * display; + XmString str; + + display = XtDisplay(data->dialog); + font = XLoadQueryFont(display, data->font_name); + font_list = gui_motif_create_fontlist(font); + + n = 0; + str = XmStringCreateLocalized("AaBbZzYy 0123456789"); + XtSetArg(args[n], XmNlabelString, str); n++; + XtSetArg(args[n], XmNfontList, font_list); n++; + + XtSetValues(data->sample, args, n); + XmStringFree(str); + + if (data->old) + { + XFreeFont(display, data->old); + XmFontListFree(data->old_list); + } + data->old = font; + data->old_list = font_list; +} + + + static Boolean +do_choice(Widget w, + SharedFontSelData *data, + XmListCallbackStruct *call_data, + enum ListSpecifier which) +{ + char *sel; + + XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel); + + if (!data->sel[which]) + data->sel[which] = XtNewString(sel); + else + { + XtFree(data->sel[which]); + if (!strcmp(data->sel[which], sel)) + { + /* unselecting current selection */ + data->sel[which] = NULL; + if (w) + XmListDeselectItem(w, call_data->item); + } + else + data->sel[which] = XtNewString(sel); + } + XtFree(sel); + + fill_lists(which, data); + + /* If there is a font selection, we display it. */ + if (data->sel[ENCODING] + && data->sel[NAME] + && data->sel[STYLE] + && data->sel[SIZE] + && strcmp(data->sel[ENCODING], wild) + && strcmp(data->sel[NAME], wild) + && strcmp(data->sel[STYLE], wild) + && strcmp(data->sel[SIZE], wild)) + { + int i; + + if (data->font_name) + XtFree(data->font_name); + data->font_name = NULL; + + for (i = 0; i < data->num; i++) + { + if (match(data, ENCODING, i) + && match(data, NAME, i) + && match(data, STYLE, i) + && match(data, SIZE, i)) + { + data->font_name = XtNewString(fn(data, i)); + break; + } + } + + if (data->font_name) + { + XmTextSetString(data->name, data->font_name); + display_sample(data); + } + else + do_dialog(VIM_ERROR, + (char_u *)_("Error"), + (char_u *)_("Invalid font specification"), + (char_u *)_("&Dismiss"), 1, NULL); + + return True; + } + else + { + int n; + XmString str; + Arg args[4]; + char *msg = _("no specific match"); + + n = 0; + str = XmStringCreateLocalized(msg); + XtSetArg(args[n], XmNlabelString, str); ++n; + XtSetValues(data->sample, args, n); + apply_fontlist(data->sample); + XmTextSetString(data->name, msg); + XmStringFree(str); + + return False; + } +} + +/*ARGSUSED*/ + static void +encoding_callback(Widget w, + SharedFontSelData *data, + XtPointer dummy) +{ + XmString str; + XmListCallbackStruct fake_data; + + XtVaGetValues(w, XmNlabelString, &str, NULL); + + if (!str) + return; + + fake_data.item = str; + + do_choice(0, data, &fake_data, ENCODING); +} + + static void +name_callback(Widget w, + SharedFontSelData *data, + XmListCallbackStruct *call_data) +{ + do_choice(w, data, call_data, NAME); +} + + static void +style_callback(Widget w, + SharedFontSelData *data, + XmListCallbackStruct *call_data) +{ + do_choice(w, data, call_data, STYLE); +} + + static void +size_callback(Widget w, + SharedFontSelData *data, + XmListCallbackStruct *call_data) +{ + do_choice(w, data, call_data, SIZE); +} + +/*ARGSUSED*/ + static void +cancel_callback(Widget w, + SharedFontSelData *data, + XmListCallbackStruct *call_data) +{ + if (data->sel[ENCODING]) + { + XtFree(data->sel[ENCODING]); + data->sel[ENCODING] = NULL; + } + if (data->sel[NAME]) + { + XtFree(data->sel[NAME]); + data->sel[NAME] = NULL; + } + if (data->sel[STYLE]) + { + XtFree(data->sel[STYLE]); + data->sel[STYLE] = NULL; + } + if (data->sel[SIZE]) + { + XtFree(data->sel[SIZE]); + data->sel[SIZE] = NULL; + } + + if (data->font_name) + XtFree(data->font_name); + data->font_name = NULL; + + data->num = 0; + XFreeFontNames(data->names); + data->names = NULL; + data->exit = True; +} + +/*ARGSUSED*/ + static void +ok_callback(Widget w, + SharedFontSelData *data, + XmPushButtonCallbackStruct *call_data) +{ + char *pattern; + char **name; + int i; + + pattern = XmTextGetString(data->name); + name = XListFonts(XtDisplay(data->dialog), pattern, 1, &i); + XtFree(pattern); + + if (i != 1) + { + do_dialog(VIM_ERROR, + (char_u *)_("Error"), + (char_u *)_("Invalid font specification"), + (char_u *)_("&Dismiss"), 1, NULL); + XFreeFontNames(name); + } + else + { + if (data->font_name) + XtFree(data->font_name); + data->font_name = XtNewString(name[0]); + + if (data->sel[ENCODING]) + { + XtFree(data->sel[ENCODING]); + data->sel[ENCODING] = NULL; + } + if (data->sel[NAME]) + { + XtFree(data->sel[NAME]); + data->sel[NAME] = NULL; + } + if (data->sel[STYLE]) + { + XtFree(data->sel[STYLE]); + data->sel[STYLE] = NULL; + } + if (data->sel[SIZE]) + { + XtFree(data->sel[SIZE]); + data->sel[SIZE] = NULL; + } + + XFreeFontNames(name); + + data->num = 0; + XFreeFontNames(data->names); + data->names = NULL; + data->exit = True; + } +} + +/* + * Returns pointer to an ASCII character string that contains the name of the + * selected font (in X format for naming fonts); it is the users responsibility + * to free the space allocated to this string. + */ + char_u * +gui_xm_select_font(char_u *current) +{ + static SharedFontSelData _data; + + Widget parent; + Widget form; + Widget separator; + Widget sub_form; + Widget size_toggle; + Widget name; + Widget disp_frame; + Widget frame; + Arg args[64]; + int n; + XmString str; + char big_font[MAX_FONT_NAME_LEN]; + SharedFontSelData *data; + + data = &_data; + + parent = vimShell; + data->names = XListFonts(XtDisplay(parent), "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", + MAX_FONTS, &data->num); + + /* + * Find the name of the biggest font less than the given limit + * MAX_DISPLAY_SIZE used to set up the initial height of the display + * widget. + */ + + { + int i; + int max; + int index = 0; + int size; + char str[128]; + + for (i = 0, max = 0; i < data->num; i++) + { + get_part(fn(data, i), 7, str); + size = atoi(str); + if ((size > max) && (size < MAX_DISPLAY_SIZE)) + { + index = i; + max = size; + } + } + strcpy(big_font, fn(data, index)); + } + data->old = XLoadQueryFont(XtDisplay(parent), big_font); + data->old_list = gui_motif_create_fontlist(data->old); + + /* Set the title of the Dialog window. */ + data->dialog = XmCreateDialogShell(parent, "fontSelector", NULL, 0); + str = XmStringCreateLocalized(_("Vim - Font Selector")); + + /* Create form popup dialog widget. */ + form = XtVaCreateWidget("form", + xmFormWidgetClass, data->dialog, + XmNdialogTitle, str, + XmNautoUnmanage, False, + XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, + NULL); + XmStringFree(str); + + sub_form = XtVaCreateManagedWidget("subForm", + xmFormWidgetClass, form, + XmNbottomAttachment, XmATTACH_FORM, + XmNbottomOffset, 4, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 4, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 4, + XmNorientation, XmVERTICAL, + NULL); + + data->ok = XtVaCreateManagedWidget(_("OK"), + xmPushButtonGadgetClass, sub_form, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 4, + NULL); + apply_fontlist(data->ok); + + data->cancel = XtVaCreateManagedWidget(_("Cancel"), + xmPushButtonGadgetClass, sub_form, + XmNrightAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, data->ok, + XmNtopOffset, 4, + XmNshowAsDefault, True, + NULL); + apply_fontlist(data->cancel); + + /* Create the separator for beauty. */ + n = 0; + XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; + XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; + XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; + XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; + XtSetArg(args[n], XmNrightWidget, sub_form); n++; + XtSetArg(args[n], XmNrightOffset, 4); n++; + separator = XmCreateSeparatorGadget(form, "separator", args, n); + XtManageChild(separator); + + /* Create font name text widget and the corresponding label. */ + data->name = XtVaCreateManagedWidget("fontName", + xmTextWidgetClass, form, + XmNbottomAttachment, XmATTACH_FORM, + XmNbottomOffset, 4, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 4, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightWidget, separator, + XmNrightOffset, 4, + XmNeditable, False, + XmNeditMode, XmSINGLE_LINE_EDIT, + XmNmaxLength, MAX_FONT_NAME_LEN, + XmNcolumns, 60, + NULL); + + str = XmStringCreateLocalized(_("Name:")); + name = XtVaCreateManagedWidget("fontNameLabel", + xmLabelGadgetClass, form, + XmNlabelString, str, + XmNuserData, data->name, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftWidget, data->name, + XmNbottomAttachment, XmATTACH_WIDGET, + XmNbottomWidget, data->name, + XmNtopOffset, 1, + NULL); + XmStringFree(str); + apply_fontlist(name); + + /* create sample display label widget */ + disp_frame = XtVaCreateManagedWidget("sampleFrame", + xmFrameWidgetClass, form, + XmNshadowType, XmSHADOW_ETCHED_IN, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 4, + XmNbottomAttachment, XmATTACH_WIDGET, + XmNbottomWidget, name, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightWidget, separator, + XmNrightOffset, 4, + XmNalignment, XmALIGNMENT_BEGINNING, + NULL); + + data->sample = XtVaCreateManagedWidget("sampleLabel", + xmLabelWidgetClass, disp_frame, + XmNleftAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNalignment, XmALIGNMENT_BEGINNING, + XmNrecomputeSize, False, + XmNfontList, data->old_list, + NULL); + + /* create toggle button */ + str = XmStringCreateLocalized(_("Show size in Points")); + size_toggle = XtVaCreateManagedWidget("sizeToggle", + xmToggleButtonGadgetClass, form, + XmNlabelString, str, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 4, + XmNbottomAttachment, XmATTACH_WIDGET, + XmNbottomWidget, disp_frame, + XmNbottomOffset, 4, + NULL); + XmStringFree(str); + apply_fontlist(size_toggle); + XtManageChild(size_toggle); + + /* Encoding pulldown menu. + */ + + data->encoding_pulldown = XmCreatePulldownMenu(form, + "encodingPulldown", NULL, 0); + str = XmStringCreateLocalized(_("Encoding:")); + n = 0; + XtSetArg(args[n], XmNsubMenuId, data->encoding_pulldown); ++n; + XtSetArg(args[n], XmNlabelString, str); ++n; + XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n; + XtSetArg(args[n], XmNleftOffset, 4); ++n; + XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n; + XtSetArg(args[n], XmNbottomWidget, size_toggle); ++n; + XtSetArg(args[n], XmNbottomOffset, 4); ++n; + XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n; + XtSetArg(args[n], XmNrightWidget, separator); ++n; + XtSetArg(args[n], XmNrightOffset, 4); ++n; + data->encoding_menu = XmCreateOptionMenu(form, "encodingMenu", args, n); + XmStringFree(str); + XmAddTabGroup(data->encoding_menu); + + /* + * Create scroll list widgets in a separate subform used to manage the + * different sizes of the lists. + */ + + sub_form = XtVaCreateManagedWidget("subForm", + xmFormWidgetClass, form, + XmNbottomAttachment, XmATTACH_WIDGET, + XmNbottomWidget, data->encoding_menu, + XmNbottomOffset, 4, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 4, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightWidget, separator, + XmNrightOffset, 4, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 2, + XmNorientation, XmVERTICAL, + NULL); + + /* font list */ + frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form, + XmNshadowThickness, 0, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_POSITION, + XmNrightPosition, 50, + NULL); + + str = XmStringCreateLocalized(_("Font:")); + name = XtVaCreateManagedWidget("nameListLabel", xmLabelGadgetClass, frame, + XmNchildType, XmFRAME_TITLE_CHILD, + XmNchildVerticalAlignment, XmALIGNMENT_CENTER, + XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, + XmNlabelString, str, + NULL); + XmStringFree(str); + apply_fontlist(name); + + n = 0; + XtSetArg(args[n], XmNvisibleItemCount, 8); ++n; + XtSetArg(args[n], XmNresizable, True); ++n; + XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n; + XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n; +#ifdef LESSTIF_VERSION + XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n; +#endif + data->list[NAME] = XmCreateScrolledList(frame, "fontList", args, n); + XtVaSetValues(name, XmNuserData, data->list[NAME], NULL); + + /* style list */ + frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form, + XmNshadowThickness, 0, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 50, + XmNleftOffset, 4, + XmNrightAttachment, XmATTACH_POSITION, + XmNrightPosition, 80, + NULL); + + str = XmStringCreateLocalized(_("Style:")); + name = XtVaCreateManagedWidget("styleListLabel", xmLabelWidgetClass, frame, + XmNchildType, XmFRAME_TITLE_CHILD, + XmNchildVerticalAlignment, XmALIGNMENT_CENTER, + XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, + XmNlabelString, str, + NULL); + XmStringFree(str); + apply_fontlist(name); + + n = 0; + XtSetArg(args[n], XmNvisibleItemCount, 8); ++n; + XtSetArg(args[n], XmNresizable, True); ++n; + XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n; + XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n; +#ifdef LESSTIF_VERSION + XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n; +#endif + data->list[STYLE] = XmCreateScrolledList(frame, "styleList", args, n); + XtVaSetValues(name, XmNuserData, data->list[STYLE], NULL); + + /* size list */ + frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form, + XmNshadowThickness, 0, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 80, + XmNleftOffset, 4, + XmNrightAttachment, XmATTACH_FORM, + NULL); + + str = XmStringCreateLocalized(_("Size:")); + name = XtVaCreateManagedWidget("sizeListLabel", xmLabelGadgetClass, frame, + XmNchildType, XmFRAME_TITLE_CHILD, + XmNchildVerticalAlignment, XmALIGNMENT_CENTER, + XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, + XmNlabelString, str, + NULL); + XmStringFree(str); + apply_fontlist(name); + + n = 0; + XtSetArg(args[n], XmNvisibleItemCount, 8); ++n; + XtSetArg(args[n], XmNresizable, True); ++n; + XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n; + XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n; +#ifdef LESSTIF_VERSION + XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n; +#endif + data->list[SIZE] = XmCreateScrolledList(frame, "sizeList", args, n); + XtVaSetValues(name, XmNuserData, data->list[SIZE], NULL); + + /* update form widgets cancel button */ + XtVaSetValues(form, XmNcancelButton, data->cancel, NULL); + + XtAddCallback(size_toggle, XmNvalueChangedCallback, + (XtCallbackProc)stoggle_callback, (XtPointer)data); + XtAddCallback(data->list[NAME], XmNbrowseSelectionCallback, + (XtCallbackProc)name_callback, (XtPointer)data); + XtAddCallback(data->list[STYLE], XmNbrowseSelectionCallback, + (XtCallbackProc)style_callback, (XtPointer)data); + XtAddCallback(data->list[SIZE], XmNbrowseSelectionCallback, + (XtCallbackProc)size_callback, (XtPointer)data); + XtAddCallback(data->ok, XmNactivateCallback, + (XtCallbackProc)ok_callback, (XtPointer)data); + XtAddCallback(data->cancel, XmNactivateCallback, + (XtCallbackProc)cancel_callback, (XtPointer)data); + + XmProcessTraversal(data->list[NAME], XmTRAVERSE_CURRENT); + + /* setup tabgroups */ + + XmAddTabGroup(data->list[NAME]); + XmAddTabGroup(data->list[STYLE]); + XmAddTabGroup(data->list[SIZE]); + XmAddTabGroup(size_toggle); + XmAddTabGroup(data->name); + XmAddTabGroup(data->ok); + XmAddTabGroup(data->cancel); + + add_cancel_action(data->dialog, (XtCallbackProc)cancel_callback, data); + + /* Preset selection data. */ + + data->exit = False; + data->in_pixels= True; + data->sel[ENCODING] = NULL; + data->sel[NAME] = NULL; + data->sel[STYLE] = NULL; + data->sel[SIZE] = NULL; + data->font_name = NULL; + + /* set up current font parameters */ + if (current && current[0] != '\0') + { + int i; + char **names; + + names = XListFonts(XtDisplay(form), (char *) current, 1, &i); + + if (i != 0) + { + char name[TEMP_BUF_SIZE]; + char style[TEMP_BUF_SIZE]; + char size[TEMP_BUF_SIZE]; + char encoding[TEMP_BUF_SIZE]; + char *found; + + found = names[0]; + + name_part(found, name); + style_part(found, style); + size_part(found, size, data->in_pixels); + encoding_part(found, encoding); + + if (strlen(name) > 0 + && strlen(style) > 0 + && strlen(size) > 0 + && strlen(encoding) > 0) + { + data->sel[NAME] = XtNewString(name); + data->sel[STYLE] = XtNewString(style); + data->sel[SIZE] = XtNewString(size); + data->sel[ENCODING] = XtNewString(encoding); + data->font_name = XtNewString(names[0]); + display_sample(data); + XmTextSetString(data->name, data->font_name); + } + else + { + /* We can't preset a symbolic name, which isn't a full font + * description. Therefore we just behave the same way as if the + * user didn't have selected anything thus far. + * + * Unfortunately there is no known way to expand an abbreviated + * font name. + */ + + data->font_name = NULL; + } + } + XFreeFontNames(names); + } + + fill_lists(NONE, data); + + /* Unfortunately LessTif doesn't align the list widget's properly. I don't + * have currently any idea how to fix this problem. + */ + XtManageChild(data->list[NAME]); + XtManageChild(data->list[STYLE]); + XtManageChild(data->list[SIZE]); + XtManageChild(data->encoding_menu); + manage_centered(form); + + /* modal event loop */ + while (!data->exit) + XtAppProcessEvent(XtWidgetToApplicationContext(data->dialog), + (XtInputMask)XtIMAll); + + XtDestroyWidget(data->dialog); + + if (data->old) + { + XFreeFont(XtDisplay(data->dialog), data->old); + XmFontListFree(data->old_list); + } + + gui_motif_synch_fonts(); + + return (char_u *) data->font_name; +} diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -107,9 +107,9 @@ coladvance(wcol) if (wcol == MAXCOL || rc == FAIL) curwin->w_valid &= ~VALID_VIRTCOL; - else + else if (*ml_get_cursor() != TAB) { - /* Virtcol is valid */ + /* Virtcol is valid when not on a TAB */ curwin->w_valid |= VALID_VIRTCOL; curwin->w_virtcol = wcol; } diff --git a/src/proto.h b/src/proto.h --- a/src/proto.h +++ b/src/proto.h @@ -194,6 +194,7 @@ extern char_u *vimpty_getenv __ARGS((con # endif # ifdef FEAT_GUI_MOTIF # include "gui_motif.pro" +# include "gui_xmdlg.pro" # endif # ifdef FEAT_GUI_ATHENA # include "gui_athena.pro" diff --git a/src/proto/gui_xmdlg.pro b/src/proto/gui_xmdlg.pro new file mode 100644 --- /dev/null +++ b/src/proto/gui_xmdlg.pro @@ -0,0 +1,3 @@ +/* gui_xmdlg.c */ +char_u *gui_xm_select_font __ARGS((char_u *current)); +/* vim: set ft=c : */ diff --git a/src/workshop.c b/src/workshop.c --- a/src/workshop.c +++ b/src/workshop.c @@ -15,10 +15,10 @@ #include #include #include +#include #include #include #include -#include #include #ifdef HAVE_LIBGEN_H # include