2 Support of multiply editors and viewers.
4 Original idea and code: Oleg "Olegarch" Konovalov <olegarch@linuxinside.com>
6 Copyright (C) 2009-2016
7 Free Software Foundation, Inc.
10 Daniel Borca <dborca@yahoo.com>, 2007
11 Andrew Borodin <aborodin@vmail.ru>, 2010, 2013
13 This file is part of the Midnight Commander.
15 The Midnight Commander is free software: you can redistribute it
16 and/or modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation, either version 3 of the License,
18 or (at your option) any later version.
20 The Midnight Commander is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 /** \file dialog-switch.c
30 * \brief Source: support of multiply editors and viewers.
35 #include "lib/global.h"
36 #include "lib/tty/tty.h" /* LINES, COLS */
37 #include "lib/tty/color.h" /* tty_set_normal_attrs() */
39 #include "lib/tty/win.h" /* do_enter_ca_mode() */
41 #include "lib/widget.h"
42 #include "lib/event.h"
44 /*** global variables ****************************************************************************/
46 WDialog
*midnight_dlg
= NULL
;
48 /*** file scope macro definitions ****************************************************************/
50 /*** file scope type declarations ****************************************************************/
52 /*** file scope variables ************************************************************************/
54 /* List of dialogs: filemanagers, editors, viewers */
55 static GList
*mc_dialogs
= NULL
;
56 /* Currently active dialog */
57 static GList
*mc_current
= NULL
;
58 /* Is there any dialogs that we have to run after returning to the manager from another dialog */
59 static gboolean dialog_switch_pending
= FALSE
;
61 /*** file scope functions ************************************************************************/
62 /* --------------------------------------------------------------------------------------------- */
67 return (n
<= 9) ? '0' + n
: 'a' + n
- 10;
70 /* --------------------------------------------------------------------------------------------- */
73 dialog_switch_suspend (void *data
, void *user_data
)
77 if (data
!= mc_current
->data
)
78 DIALOG (data
)->state
= DLG_SUSPENDED
;
81 /* --------------------------------------------------------------------------------------------- */
84 dialog_switch_goto (GList
* dlg
)
86 if (mc_current
!= dlg
)
88 WDialog
*old
= DIALOG (mc_current
->data
);
92 if (old
== midnight_dlg
)
94 /* switch from panels to another dialog (editor, viewer, etc) */
95 dialog_switch_pending
= TRUE
;
96 dialog_switch_process_pending ();
100 /* switch from editor, viewer, etc to another dialog */
101 old
->state
= DLG_SUSPENDED
;
103 if (DIALOG (dlg
->data
) != midnight_dlg
)
104 /* switch to another editor, viewer, etc */
105 /* return to panels before run the required dialog */
106 dialog_switch_pending
= TRUE
;
109 /* switch to panels */
110 midnight_dlg
->state
= DLG_ACTIVE
;
117 /* --------------------------------------------------------------------------------------------- */
120 dlg_resize_cb (void *data
, void *user_data
)
125 if (d
->state
== DLG_ACTIVE
)
126 send_message (d
, NULL
, MSG_RESIZE
, 0, NULL
);
128 d
->winch_pending
= TRUE
;
131 /* --------------------------------------------------------------------------------------------- */
132 /*** public functions ****************************************************************************/
133 /* --------------------------------------------------------------------------------------------- */
136 dialog_switch_add (WDialog
* h
)
140 dlg
= g_list_find (mc_dialogs
, h
);
146 mc_dialogs
= g_list_prepend (mc_dialogs
, h
);
147 mc_current
= mc_dialogs
;
150 /* suspend forced all other screens */
151 g_list_foreach (mc_dialogs
, dialog_switch_suspend
, NULL
);
154 /* --------------------------------------------------------------------------------------------- */
157 dialog_switch_remove (WDialog
* h
)
161 if (DIALOG (mc_current
->data
) == h
)
164 this = g_list_find (mc_dialogs
, h
);
166 mc_dialogs
= g_list_delete_link (mc_dialogs
, this);
168 /* adjust current dialog */
170 mc_current
= g_list_find (mc_dialogs
, DIALOG (top_dlg
->data
));
172 mc_current
= mc_dialogs
;
174 /* resume forced the current screen */
175 if (mc_current
!= NULL
)
176 DIALOG (mc_current
->data
)->state
= DLG_ACTIVE
;
179 /* --------------------------------------------------------------------------------------------- */
182 dialog_switch_num (void)
184 return g_list_length (mc_dialogs
);
187 /* --------------------------------------------------------------------------------------------- */
190 dialog_switch_next (void)
194 if (mc_global
.midnight_shutdown
|| mc_current
== NULL
)
197 next
= g_list_next (mc_current
);
201 dialog_switch_goto (next
);
204 /* --------------------------------------------------------------------------------------------- */
207 dialog_switch_prev (void)
211 if (mc_global
.midnight_shutdown
|| mc_current
== NULL
)
214 prev
= g_list_previous (mc_current
);
216 prev
= g_list_last (mc_dialogs
);
218 dialog_switch_goto (prev
);
221 /* --------------------------------------------------------------------------------------------- */
224 dialog_switch_list (void)
226 const size_t dlg_num
= g_list_length (mc_dialogs
);
233 if (mc_global
.midnight_shutdown
|| mc_current
== NULL
)
236 lines
= min ((size_t) (LINES
* 2 / 3), dlg_num
);
239 listbox
= create_listbox_window (lines
, cols
, _("Screens"), "[Screen selector]");
241 for (h
= mc_dialogs
; h
!= NULL
; h
= g_list_next (h
))
246 dlg
= DIALOG (h
->data
);
248 if ((dlg
!= NULL
) && (dlg
->get_title
!= NULL
))
249 title
= dlg
->get_title (dlg
, WIDGET (listbox
->list
)->cols
- 2);
251 title
= g_strdup ("");
253 listbox_add_item (listbox
->list
, LISTBOX_APPEND_BEFORE
, get_hotkey (i
++), title
, NULL
,
259 listbox_select_entry (listbox
->list
, dlg_num
- 1 - g_list_position (mc_dialogs
, mc_current
));
260 rv
= run_listbox (listbox
);
264 h
= g_list_nth (mc_dialogs
, dlg_num
- 1 - rv
);
265 dialog_switch_goto (h
);
269 /* --------------------------------------------------------------------------------------------- */
272 dialog_switch_process_pending (void)
276 while (dialog_switch_pending
)
278 WDialog
*h
= DIALOG (mc_current
->data
);
280 dialog_switch_pending
= FALSE
;
281 h
->state
= DLG_SUSPENDED
;
283 if (h
->state
== DLG_CLOSED
)
287 /* return to panels */
288 if (mc_global
.mc_run_mode
== MC_RUN_FULL
)
290 mc_current
= g_list_find (mc_dialogs
, midnight_dlg
);
291 mc_event_raise (MCEVENT_GROUP_FILEMANAGER
, "update_panels", NULL
);
301 /* --------------------------------------------------------------------------------------------- */
304 dialog_switch_got_winch (void)
308 for (dlg
= mc_dialogs
; dlg
!= NULL
; dlg
= g_list_next (dlg
))
309 if (dlg
!= mc_current
)
310 DIALOG (dlg
->data
)->winch_pending
= TRUE
;
313 /* --------------------------------------------------------------------------------------------- */
316 dialog_switch_shutdown (void)
318 while (mc_dialogs
!= NULL
)
320 WDialog
*dlg
= DIALOG (mc_dialogs
->data
);
327 /* --------------------------------------------------------------------------------------------- */
332 tty_set_normal_attrs ();
333 tty_fill_region (0, 0, LINES
, COLS
, ' ');
337 /* --------------------------------------------------------------------------------------------- */
340 repaint_screen (void)
346 /* --------------------------------------------------------------------------------------------- */
351 #ifdef ENABLE_BACKGROUND
352 if (mc_global
.we_are_background
)
354 #endif /* ENABLE_BACKGROUND */
355 if (mc_global
.tty
.winch_flag
== 0)
359 /* if winch was caugth, we should do not only redraw screen, but
360 reposition/resize all */
361 dialog_change_screen_size ();
365 /* --------------------------------------------------------------------------------------------- */
368 dialog_change_screen_size (void)
370 mc_global
.tty
.winch_flag
= 0;
372 tty_change_screen_size ();
380 /* Inform all suspending dialogs */
381 dialog_switch_got_winch ();
382 /* Inform all running dialogs */
383 g_list_foreach (top_dlg
, (GFunc
) dlg_resize_cb
, NULL
);
385 /* Now, force the redraw */
389 /* --------------------------------------------------------------------------------------------- */