Added two macro examples:
[midnight-commander/osp/fanda.git] / lib / widget / dialog-switch.c
blob49bb5cffaca0fb92d913925a4c93ce6ed10fdf80
1 /*
2 * Copyright (c) 2009, 2010 Free Software Foundation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 * Original idea and code: Oleg "Olegarch" Konovalov <olegarch@linuxinside.com>
19 * Written by: 2007 Daniel Borca <dborca@yahoo.com>
20 * 2010 Andrew Borodin <aborodin@vmail.ru>
23 /** \file dialog-switch.c
24 * \brief Source: support of multiply editors and viewers.
27 #include <config.h>
29 #include "lib/global.h"
30 #include "lib/tty/tty.h" /* LINES, COLS */
31 #include "lib/widget.h"
33 /* TODO: these includes should be removed! */
34 #include "src/filemanager/layout.h" /* repaint_screen() */
35 #include "src/filemanager/midnight.h" /* midnight_dlg */
36 #include "src/main.h" /* midnight_shutdown */
38 /*** global variables ****************************************************************************/
40 /*** file scope macro definitions ****************************************************************/
42 /*** file scope type declarations ****************************************************************/
44 /*** file scope variables ************************************************************************/
46 /* List of dialogs: filemanagers, editors, viewers */
47 static GList *mc_dialogs = NULL;
48 /* Currently active dialog */
49 static GList *mc_current = NULL;
50 /* Is there any dialogs that we have to run after returning to the manager from another dialog */
51 static gboolean dialog_switch_pending = FALSE;
53 /*** file scope functions ************************************************************************/
54 /* --------------------------------------------------------------------------------------------- */
56 static unsigned char
57 get_hotkey (int n)
59 return (n <= 9) ? '0' + n : 'a' + n - 10;
62 /* --------------------------------------------------------------------------------------------- */
64 static void
65 dialog_switch_goto (GList * dlg)
67 if (mc_current != dlg)
69 Dlg_head *old = (Dlg_head *) mc_current->data;
71 mc_current = dlg;
73 if (old == midnight_dlg)
75 /* switch from panels to another dialog (editor, viewer, etc) */
76 dialog_switch_pending = TRUE;
77 dialog_switch_process_pending ();
79 else
81 /* switch from editor, viewer, etc to another dialog */
82 old->state = DLG_SUSPENDED;
84 if ((Dlg_head *) dlg->data != midnight_dlg)
85 /* switch to another editor, viewer, etc */
86 /* return to panels before run the required dialog */
87 dialog_switch_pending = TRUE;
88 else
89 /* switch to panels */
90 do_refresh ();
95 /* --------------------------------------------------------------------------------------------- */
96 /*** public functions ****************************************************************************/
97 /* --------------------------------------------------------------------------------------------- */
99 void
100 dialog_switch_add (Dlg_head * h)
102 GList *dlg;
104 dlg = g_list_find (mc_dialogs, h);
106 if (dlg != NULL)
107 mc_current = dlg;
108 else
110 mc_dialogs = g_list_prepend (mc_dialogs, h);
111 mc_current = mc_dialogs;
115 /* --------------------------------------------------------------------------------------------- */
117 void
118 dialog_switch_remove (Dlg_head * h)
120 GList *this;
122 if ((Dlg_head *) mc_current->data == h)
123 this = mc_current;
124 else
125 this = g_list_find (mc_dialogs, h);
127 mc_dialogs = g_list_delete_link (mc_dialogs, this);
129 /* adjust current dialog */
130 if (top_dlg != NULL)
131 mc_current = g_list_find (mc_dialogs, (Dlg_head *) top_dlg->data);
132 else
133 mc_current = mc_dialogs;
136 /* --------------------------------------------------------------------------------------------- */
138 size_t
139 dialog_switch_num (void)
141 return g_list_length (mc_dialogs);
144 /* --------------------------------------------------------------------------------------------- */
146 void
147 dialog_switch_next (void)
149 GList *next;
151 if (midnight_shutdown || mc_current == NULL)
152 return;
154 next = g_list_next (mc_current);
155 if (next == NULL)
156 next = mc_dialogs;
158 dialog_switch_goto (next);
161 /* --------------------------------------------------------------------------------------------- */
163 void
164 dialog_switch_prev (void)
166 GList *prev;
168 if (midnight_shutdown || mc_current == NULL)
169 return;
171 prev = g_list_previous (mc_current);
172 if (prev == NULL)
173 prev = g_list_last (mc_dialogs);
175 dialog_switch_goto (prev);
178 /* --------------------------------------------------------------------------------------------- */
180 void
181 dialog_switch_list (void)
183 const size_t dlg_num = g_list_length (mc_dialogs);
184 int lines, cols;
185 Listbox *listbox;
186 GList *h;
187 int i = 0;
188 int rv;
190 if (midnight_shutdown || mc_current == NULL)
191 return;
193 lines = min ((size_t) (LINES * 2 / 3), dlg_num);
194 cols = COLS * 2 / 3;
196 listbox = create_listbox_window (lines, cols, _("Screens"), "[Screen selector]");
198 for (h = mc_dialogs; h != NULL; h = g_list_next (h))
200 Dlg_head *dlg;
201 char *title;
203 dlg = (Dlg_head *) h->data;
205 if ((dlg != NULL) && (dlg->get_title != NULL))
206 title = dlg->get_title (dlg, listbox->list->widget.cols - 2); /* FIXME! */
207 else
208 title = g_strdup ("");
210 listbox_add_item (listbox->list, LISTBOX_APPEND_BEFORE, get_hotkey (i++), title, NULL);
212 g_free (title);
215 listbox_select_entry (listbox->list, dlg_num - 1 - g_list_position (mc_dialogs, mc_current));
216 rv = run_listbox (listbox);
218 if (rv >= 0)
220 h = g_list_nth (mc_dialogs, dlg_num - 1 - rv);
221 dialog_switch_goto (h);
225 /* --------------------------------------------------------------------------------------------- */
228 dialog_switch_process_pending (void)
230 int ret = 0;
232 while (dialog_switch_pending)
234 Dlg_head *h = (Dlg_head *) mc_current->data;
236 dialog_switch_pending = FALSE;
237 h->state = DLG_SUSPENDED;
238 ret = run_dlg (h);
239 if (h->state == DLG_CLOSED)
241 destroy_dlg (h);
242 /* return to panels */
243 if (mc_run_mode == MC_RUN_FULL)
245 mc_current = g_list_find (mc_dialogs, midnight_dlg);
246 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
251 repaint_screen ();
253 return ret;
256 /* --------------------------------------------------------------------------------------------- */
258 void
259 dialog_switch_got_winch (void)
261 GList *dlg;
263 for (dlg = mc_dialogs; dlg != NULL; dlg = g_list_next (dlg))
264 if (dlg != mc_current)
265 ((Dlg_head *) dlg->data)->winch_pending = TRUE;
268 /* --------------------------------------------------------------------------------------------- */
270 void
271 dialog_switch_shutdown (void)
273 while (mc_dialogs != NULL)
275 Dlg_head *dlg = (Dlg_head *) mc_dialogs->data;
277 run_dlg (dlg);
278 destroy_dlg (dlg);
282 /* --------------------------------------------------------------------------------------------- */