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.
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 /* --------------------------------------------------------------------------------------------- */
59 return (n
<= 9) ? '0' + n
: 'a' + n
- 10;
62 /* --------------------------------------------------------------------------------------------- */
65 dialog_switch_goto (GList
* dlg
)
67 if (mc_current
!= dlg
)
69 Dlg_head
*old
= (Dlg_head
*) mc_current
->data
;
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 ();
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
;
89 /* switch to panels */
95 /* --------------------------------------------------------------------------------------------- */
96 /*** public functions ****************************************************************************/
97 /* --------------------------------------------------------------------------------------------- */
100 dialog_switch_add (Dlg_head
* h
)
104 dlg
= g_list_find (mc_dialogs
, h
);
110 mc_dialogs
= g_list_prepend (mc_dialogs
, h
);
111 mc_current
= mc_dialogs
;
115 /* --------------------------------------------------------------------------------------------- */
118 dialog_switch_remove (Dlg_head
* h
)
122 if ((Dlg_head
*) mc_current
->data
== h
)
125 this = g_list_find (mc_dialogs
, h
);
127 mc_dialogs
= g_list_delete_link (mc_dialogs
, this);
129 /* adjust current dialog */
131 mc_current
= g_list_find (mc_dialogs
, (Dlg_head
*) top_dlg
->data
);
133 mc_current
= mc_dialogs
;
136 /* --------------------------------------------------------------------------------------------- */
139 dialog_switch_num (void)
141 return g_list_length (mc_dialogs
);
144 /* --------------------------------------------------------------------------------------------- */
147 dialog_switch_next (void)
151 if (midnight_shutdown
|| mc_current
== NULL
)
154 next
= g_list_next (mc_current
);
158 dialog_switch_goto (next
);
161 /* --------------------------------------------------------------------------------------------- */
164 dialog_switch_prev (void)
168 if (midnight_shutdown
|| mc_current
== NULL
)
171 prev
= g_list_previous (mc_current
);
173 prev
= g_list_last (mc_dialogs
);
175 dialog_switch_goto (prev
);
178 /* --------------------------------------------------------------------------------------------- */
181 dialog_switch_list (void)
183 const size_t dlg_num
= g_list_length (mc_dialogs
);
190 if (midnight_shutdown
|| mc_current
== NULL
)
193 lines
= min ((size_t) (LINES
* 2 / 3), dlg_num
);
196 listbox
= create_listbox_window (lines
, cols
, _("Screens"), "[Screen selector]");
198 for (h
= mc_dialogs
; h
!= NULL
; h
= g_list_next (h
))
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! */
208 title
= g_strdup ("");
210 listbox_add_item (listbox
->list
, LISTBOX_APPEND_BEFORE
, get_hotkey (i
++), title
, NULL
);
215 listbox_select_entry (listbox
->list
, dlg_num
- 1 - g_list_position (mc_dialogs
, mc_current
));
216 rv
= run_listbox (listbox
);
220 h
= g_list_nth (mc_dialogs
, dlg_num
- 1 - rv
);
221 dialog_switch_goto (h
);
225 /* --------------------------------------------------------------------------------------------- */
228 dialog_switch_process_pending (void)
232 while (dialog_switch_pending
)
234 Dlg_head
*h
= (Dlg_head
*) mc_current
->data
;
236 dialog_switch_pending
= FALSE
;
237 h
->state
= DLG_SUSPENDED
;
239 if (h
->state
== DLG_CLOSED
)
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
);
256 /* --------------------------------------------------------------------------------------------- */
259 dialog_switch_got_winch (void)
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 /* --------------------------------------------------------------------------------------------- */
271 dialog_switch_shutdown (void)
273 while (mc_dialogs
!= NULL
)
275 Dlg_head
*dlg
= (Dlg_head
*) mc_dialogs
->data
;
282 /* --------------------------------------------------------------------------------------------- */