aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Rumney2008-04-10 15:20:07 +0000
committerJason Rumney2008-04-10 15:20:07 +0000
commit31403b2446c0f130398c64bdfd3a0b81cc87baac (patch)
tree1b4534a04bd1c1da4a42fda014d4bbff85d0fc45
parenta45868562f9b4719c61512cd646db476ca4a0dad (diff)
downloademacs-31403b2446c0f130398c64bdfd3a0b81cc87baac.tar.gz
emacs-31403b2446c0f130398c64bdfd3a0b81cc87baac.zip
(is_simple_dialog, simple_dialog_show): New functions.
(Fx_popup_dialog): Handle simple yes/no questions as dialogs.
-rw-r--r--src/ChangeLog3
-rw-r--r--src/w32menu.c181
2 files changed, 163 insertions, 21 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index f36731450d4..34edb2370b3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,8 @@
12008-04-10 Jason Rumney <jasonr@gnu.org> 12008-04-10 Jason Rumney <jasonr@gnu.org>
2 2
3 * w32menu.c (is_simple_dialog, simple_dialog_show): New functions.
4 (Fx_popup_dialog): Handle simple yes/no questions as dialogs.
5
3 * w32.c (logon_network_drive): Also logon to remote drives that 6 * w32.c (logon_network_drive): Also logon to remote drives that
4 are mapped to drive letters. 7 are mapped to drive letters.
5 8
diff --git a/src/w32menu.c b/src/w32menu.c
index f4857eb9d10..1f8561210c1 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -168,22 +168,28 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
168 168
169extern Lisp_Object Qmenu_bar_update_hook; 169extern Lisp_Object Qmenu_bar_update_hook;
170 170
171void set_frame_menubar (); 171void set_frame_menubar P_ ((FRAME_PTR, int, int));
172 172
173static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 173static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
174 Lisp_Object, Lisp_Object, Lisp_Object, 174 Lisp_Object, Lisp_Object, Lisp_Object,
175 Lisp_Object, Lisp_Object)); 175 Lisp_Object, Lisp_Object));
176#ifdef HAVE_DIALOGS 176#ifdef HAVE_DIALOGS
177static Lisp_Object w32_dialog_show (); 177static Lisp_Object w32_dialog_show P_ ((FRAME_PTR, int, Lisp_Object, char**));
178#else
179static int is_simple_dialog P_ ((Lisp_Object));
180static Lisp_Object simple_dialog_show P_ ((FRAME_PTR, Lisp_Object, Lisp_Object));
178#endif 181#endif
179static Lisp_Object w32_menu_show (); 182static Lisp_Object w32_menu_show P_ ((FRAME_PTR, int, int, int, int,
180 183 Lisp_Object, char **));
181static void keymap_panes (); 184
182static void single_keymap_panes (); 185static void keymap_panes P_ ((Lisp_Object *, int, int));
183static void single_menu_item (); 186static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
184static void list_of_panes (); 187 int, int));
185static void list_of_items (); 188static void single_menu_item P_ ((Lisp_Object, Lisp_Object,
186void w32_free_menu_strings (HWND); 189 Lisp_Object *, int, int));
190static void list_of_panes P_ ((Lisp_Object));
191static void list_of_items P_ ((Lisp_Object));
192void w32_free_menu_strings P_((HWND));
187 193
188/* This holds a Lisp vector that holds the results of decoding 194/* This holds a Lisp vector that holds the results of decoding
189 the keymaps or alist-of-alists that specify a menu. 195 the keymaps or alist-of-alists that specify a menu.
@@ -928,17 +934,23 @@ otherwise it is "Question". */)
928 CHECK_WINDOW (window); 934 CHECK_WINDOW (window);
929 935
930#ifndef HAVE_DIALOGS 936#ifndef HAVE_DIALOGS
931 /* Display a menu with these alternatives 937
932 in the middle of frame F. */
933 { 938 {
934 Lisp_Object x, y, frame, newpos; 939 /* Handle simple Yes/No choices as MessageBox popups. */
935 XSETFRAME (frame, f); 940 if (is_simple_dialog (contents))
936 XSETINT (x, x_pixel_width (f) / 2); 941 return simple_dialog_show (f, contents, header);
937 XSETINT (y, x_pixel_height (f) / 2); 942 else
938 newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil)); 943 {
939 944 /* Display a menu with these alternatives
940 return Fx_popup_menu (newpos, 945 in the middle of frame F. */
941 Fcons (Fcar (contents), Fcons (contents, Qnil))); 946 Lisp_Object x, y, frame, newpos;
947 XSETFRAME (frame, f);
948 XSETINT (x, x_pixel_width (f) / 2);
949 XSETINT (y, x_pixel_height (f) / 2);
950 newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil));
951 return Fx_popup_menu (newpos,
952 Fcons (Fcar (contents), Fcons (contents, Qnil)));
953 }
942 } 954 }
943#else /* HAVE_DIALOGS */ 955#else /* HAVE_DIALOGS */
944 { 956 {
@@ -2001,6 +2013,29 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
2001 2013
2002 2014
2003#ifdef HAVE_DIALOGS 2015#ifdef HAVE_DIALOGS
2016/* TODO: On Windows, there are two ways of defining a dialog.
2017
2018 1. Create a predefined dialog resource and include it in nt/emacs.rc.
2019 Using this method, we could then set the titles and make unneeded
2020 buttons invisible before displaying the dialog. Everything would
2021 be a fixed size though, so there is a risk that text does not
2022 fit on a button.
2023 2. Create the dialog template in memory on the fly. This allows us
2024 to size the dialog and buttons dynamically, probably giving more
2025 natural looking results for dialogs with few buttons, and eliminating
2026 the problem of text overflowing the buttons. But the API for this is
2027 quite complex - structures have to be allocated in particular ways,
2028 text content is tacked onto the end of structures in variable length
2029 arrays with further structures tacked on after these, there are
2030 certain alignment requirements for all this, and we have to
2031 measure all the text and convert to "dialog coordinates" to figure
2032 out how big to make everything.
2033
2034 For now, we'll just stick with menus for dialogs that are more
2035 complicated than simple yes/no type questions for which we can use
2036 the MessageBox function.
2037*/
2038
2004static char * button_names [] = { 2039static char * button_names [] = {
2005 "button1", "button2", "button3", "button4", "button5", 2040 "button1", "button2", "button3", "button4", "button5",
2006 "button6", "button7", "button8", "button9", "button10" }; 2041 "button6", "button7", "button8", "button9", "button10" };
@@ -2192,7 +2227,111 @@ w32_dialog_show (f, keymaps, title, header, error)
2192 2227
2193 return Qnil; 2228 return Qnil;
2194} 2229}
2195#endif /* HAVE_DIALOGS */ 2230#else /* !HAVE_DIALOGS */
2231
2232/* Currently we only handle Yes No dialogs (y-or-n-p and yes-or-no-p) as
2233 simple dialogs. We could handle a few more, but I'm not aware of
2234 anywhere in Emacs that uses the other specific dialog choices that
2235 MessageBox provides. */
2236
2237static int is_simple_dialog (contents)
2238 Lisp_Object contents;
2239{
2240 Lisp_Object options = XCDR (contents);
2241 Lisp_Object name, yes, no, other;
2242
2243 yes = build_string ("Yes");
2244 no = build_string ("No");
2245
2246 if (!CONSP (options))
2247 return 0;
2248
2249 name = XCAR (XCAR (options));
2250 if (!CONSP (options))
2251 return 0;
2252
2253 if (!NILP (Fstring_equal (name, yes)))
2254 other = no;
2255 else if (!NILP (Fstring_equal (name, no)))
2256 other = yes;
2257 else
2258 return 0;
2259
2260 options = XCDR (options);
2261 if (!CONSP (options))
2262 return 0;
2263
2264 name = XCAR (XCAR (options));
2265 if (NILP (Fstring_equal (name, other)))
2266 return 0;
2267
2268 /* Check there are no more options. */
2269 options = XCDR (options);
2270 return !(CONSP (options));
2271}
2272
2273static Lisp_Object simple_dialog_show (f, contents, header)
2274 FRAME_PTR f;
2275 Lisp_Object contents, header;
2276{
2277 int answer;
2278 UINT type;
2279 char *text, *title;
2280 Lisp_Object lispy_answer = Qnil, temp = XCAR (contents);
2281
2282 if (STRINGP (temp))
2283 text = SDATA (temp);
2284 else
2285 text = "";
2286
2287 if (NILP (header))
2288 {
2289 title = "Question";
2290 type = MB_ICONQUESTION;
2291 }
2292 else
2293 {
2294 title = "Information";
2295 type = MB_ICONINFORMATION;
2296 }
2297 type |= MB_YESNO;
2298
2299 /* Since we only handle Yes/No dialogs, and we already checked
2300 is_simple_dialog, we don't need to worry about checking contents
2301 to see what type of dialog to use. */
2302 answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type);
2303
2304 if (answer == IDYES)
2305 lispy_answer = build_string ("Yes");
2306 else if (answer == IDNO)
2307 lispy_answer = build_string ("No");
2308 else
2309 Fsignal (Qquit, Qnil);
2310
2311 for (temp = XCDR (contents); CONSP (temp); temp = XCDR (temp))
2312 {
2313 Lisp_Object item, name, value;
2314 item = XCAR (temp);
2315 if (CONSP (item))
2316 {
2317 name = XCAR (item);
2318 value = XCDR (item);
2319 }
2320 else
2321 {
2322 name = item;
2323 value = Qnil;
2324 }
2325
2326 if (!NILP (Fstring_equal (name, lispy_answer)))
2327 {
2328 return value;
2329 }
2330 }
2331 Fsignal (Qquit, Qnil);
2332 return Qnil;
2333}
2334#endif /* !HAVE_DIALOGS */
2196 2335
2197 2336
2198/* Is this item a separator? */ 2337/* Is this item a separator? */