1
1

Support of multiple editors and viewers.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Этот коммит содержится в:
Andrew Borodin 2010-04-18 14:58:18 +04:00
родитель 936bb2e5f0
Коммит 56bbdeb15f
16 изменённых файлов: 357 добавлений и 23 удалений

Просмотреть файл

@ -238,6 +238,7 @@ CmdFilteredView = alt-exclamation
CmdSelect = kpplus
CmdUnselect = kpminus
CmdReverseSelection = kpasterisk
CmdDialogList = alt-prime
ExtMap1 = ctrl-x
[main:xmap]
@ -377,6 +378,10 @@ DialogNextItem = right; down
DialogHelp = f1
DialogSuspend = ctrl-z
DialogRefresh = ctrl-l
CmdDialogList = alt-prime
CmdDialogNext = alt-rbrace
CmdDialogPrev = alt-lbrace
[diffviewer]
DiffDisplaySymbols = alt-s; s

Просмотреть файл

@ -242,6 +242,7 @@ CmdFilteredView = alt-exclamation
CmdSelect = kpplus
CmdUnselect = kpminus
CmdReverseSelection = kpasterisk
CmdDialogList = alt-prime
ExtMap1 = ctrl-x
[main:xmap]
@ -381,6 +382,10 @@ DialogNextItem = right; down
DialogHelp = f1
DialogSuspend = ctrl-z
DialogRefresh = ctrl-l
CmdDialogList = alt-prime
CmdDialogNext = alt-rbrace
CmdDialogPrev = alt-lbrace
[diffviewer]
DiffDisplaySymbols = alt-s; s

Просмотреть файл

@ -57,6 +57,7 @@ endif
SRC_mc_widgets = \
dialog.c dialog.h \
dialog-switch.c dialog-switch.h \
menu.c menu.h \
screen.c panel.h \
tree.c tree.h \

Просмотреть файл

@ -67,6 +67,7 @@
#include "subshell.h" /* use_subshell */
#include "consaver/cons.saver.h" /* console_flag */
#include "dialog.h" /* Widget */
#include "dialog-switch.h"
#include "wtools.h" /* message() */
#include "main.h" /* change_panel() */
#include "panel.h" /* current_panel */
@ -159,7 +160,7 @@ view_file_at_line (const char *filename, int plain_view, int internal, int start
if (changed_magic_flag && !mcview_altered_magic_flag)
mcview_default_magic_flag = 1;
repaint_screen ();
dialog_switch_process_pending ();
}
else if (internal)
{
@ -184,7 +185,7 @@ view_file_at_line (const char *filename, int plain_view, int internal, int start
move_dir = 0;
}
repaint_screen ();
dialog_switch_process_pending ();
}
}
else
@ -329,6 +330,7 @@ filtered_view_cmd (void)
{
mcview_viewer (command, "", 0);
g_free (command);
dialog_switch_process_pending ();
}
}
@ -353,11 +355,16 @@ do_edit_at_line (const char *what, int start_line)
}
execute_with_vfs_arg (editor, what);
}
if (mc_run_mode == MC_RUN_FULL)
{
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
#ifdef USE_INTERNAL_EDIT
if (use_internal_edit)
dialog_switch_process_pending ();
else
#endif /* USE_INTERNAL_EDIT */
repaint_screen ();
}
}
static void
@ -983,10 +990,9 @@ diff_view_cmd (void)
dview_diff_cmd ();
if (mc_run_mode == MC_RUN_FULL)
{
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
dialog_switch_process_pending ();
}
#endif

Просмотреть файл

@ -387,6 +387,9 @@
#define CK_DiffViewCmd 7076
#define CK_PanelOptionsBox 7077
#define CK_RelativeSymlinkCmd 7078
#define CK_DialogListCmd 7079
#define CK_DialogNextCmd 7080
#define CK_DialogPrevCmd 7081
/* panels */
#define CK_PanelChdirOtherPanel 8001

234
src/dialog-switch.c Обычный файл
Просмотреть файл

@ -0,0 +1,234 @@
/*
* Copyright (c) 2009, 2010 Free Software Foundation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Original idea and code: Oleg "Olegarch" Konovalov <olegarch@linuxinside.com>
* Written by: 2007 Daniel Borca <dborca@yahoo.com>
* 2010 Andrew Borodin <aborodin@vmail.ru>
*/
/** \file dialog-switch.c
* \brief Source: support of multiply editors and viewers.
*/
#include <config.h>
#include "lib/global.h"
#include "lib/tty/tty.h" /* LINES, COLS */
#include "dialog.h"
#include "widget.h"
#include "layout.h" /* repaint_screen() */
#include "main-widgets.h" /* midnight_dlg */
#include "main.h" /* midnight_shutdown */
#include "wtools.h" /* Listbox */
#include "dialog-switch.h"
/*** global variables **************************************************/
/*** file scope macro definitions **************************************/
/*** file scope type declarations **************************************/
/*** file scope variables **********************************************/
/* List of dialogs: filemanagers, editors, viewers */
static GList *mc_dialogs = NULL;
/* Currently active dialog */
static GList *mc_current = NULL;
/* Is there any dialogs that we have to run after returning to the manager from another dialog */
static gboolean dialog_switch_pending = FALSE;
/*** file scope functions **********************************************/
static unsigned char
get_hotkey (int n)
{
return (n <= 9) ? '0' + n : 'a' + n - 10;
}
static void
dialog_switch_goto (GList *dlg)
{
if (mc_current != dlg)
{
Dlg_head *old = (Dlg_head *) mc_current->data;
mc_current = dlg;
if (old == midnight_dlg)
{
/* switch from panels to another dialog (editor, viewer, etc) */
dialog_switch_pending = TRUE;
dialog_switch_process_pending ();
}
else
{
/* switch from editor, viewer, etc to another dialog */
old->state = DLG_SUSPENDED;
if ((Dlg_head *) dlg->data != midnight_dlg)
/* switch to another editor, viewer, etc */
/* return to panels before run the required dialog */
dialog_switch_pending = TRUE;
else
/* switch to panels */
do_refresh ();
}
}
}
/*** public functions **************************************************/
void
dialog_switch_add (Dlg_head *h)
{
GList *dlg;
dlg = g_list_find (mc_dialogs, h);
if (dlg != NULL)
mc_current = dlg;
else
{
mc_dialogs = g_list_prepend (mc_dialogs, h);
mc_current = mc_dialogs;
}
}
void
dialog_switch_remove (Dlg_head *h)
{
GList *this;
if ((Dlg_head *) mc_current->data == h)
this = mc_current;
else
this = g_list_find (mc_dialogs, h);
if (this != NULL)
{
GList *next;
next = g_list_next (this);
mc_dialogs = g_list_delete_link (mc_dialogs, this);
mc_current = next == NULL ? mc_dialogs : next;
}
}
void
dialog_switch_next (void)
{
GList *next;
if (midnight_shutdown || mc_current == NULL)
return;
next = g_list_next (mc_current);
if (next == NULL)
next = mc_dialogs;
dialog_switch_goto (next);
}
void
dialog_switch_prev (void)
{
GList *prev;
if (midnight_shutdown || mc_current == NULL)
return;
prev = g_list_previous (mc_current);
if (prev == NULL)
prev = g_list_last (mc_dialogs);
dialog_switch_goto (prev);
}
void
dialog_switch_list (void)
{
const size_t dlg_num = g_list_length (mc_dialogs);
int lines, cols;
Listbox *listbox;
GList *h;
int i = 0;
int rv;
if (midnight_shutdown || mc_current == NULL)
return;
lines = min ((size_t) (LINES * 2/3), dlg_num);
cols = COLS * 2/3;
listbox = create_listbox_window (lines, cols, _("Screens"), "[Screen selector]");
for (h = mc_dialogs; h != NULL; h = g_list_next (h))
{
Dlg_head *dlg;
char *title;
dlg = (Dlg_head *) h->data;
if ((dlg != NULL) && (dlg->get_title != NULL))
title = dlg->get_title (dlg, listbox->list->widget.cols - 2); /* FIXME! */
else
title = g_strdup ("");
listbox_add_item (listbox->list, LISTBOX_APPEND_BEFORE, get_hotkey (i++), title, NULL);
g_free (title);
}
listbox_select_entry (listbox->list, dlg_num - 1 - g_list_position (mc_dialogs, mc_current));
rv = run_listbox (listbox);
if (rv >= 0)
{
h = g_list_nth (mc_dialogs, dlg_num - 1 - rv);
dialog_switch_goto (h);
}
}
int
dialog_switch_process_pending (void)
{
int ret = 0;
while (dialog_switch_pending)
{
Dlg_head *h = (Dlg_head *) mc_current->data;
dialog_switch_pending = FALSE;
h->state = DLG_SUSPENDED;
ret = run_dlg (h);
if (h->state == DLG_CLOSED)
{
destroy_dlg (h);
/* return to panels */
if (mc_run_mode == MC_RUN_FULL)
{
mc_current = g_list_find (mc_dialogs, midnight_dlg);
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
}
}
}
repaint_screen ();
return ret;
}

17
src/dialog-switch.h Обычный файл
Просмотреть файл

@ -0,0 +1,17 @@
#ifndef MC_DIALOG_SWITCH_H
#define MC_DIALOG_SWITCH_H
struct Dlg_head;
void dialog_switch_add (struct Dlg_head *h);
void dialog_switch_remove (struct Dlg_head *h);
void dialog_switch_next (void);
void dialog_switch_prev (void);
void dialog_switch_list (void);
int dialog_switch_process_pending (void);
#endif /* MC_DIALOG_SWITCH_H */

Просмотреть файл

@ -1,6 +1,6 @@
/* Dialog box features module for the Midnight Commander
Copyright (C) 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2007 Free Software Foundation, Inc.
2005, 2007, 2009, 2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -38,13 +38,15 @@
#include "lib/strutil.h"
#include "help.h" /* interactive_display() */
#include "dialog.h"
#include "layout.h"
#include "execute.h" /* suspend_cmd() */
#include "cmddef.h"
#include "keybind.h"
#include "main.h" /* fast_refresh */
#include "setup.h" /* mouse_close_dialog */
#include "dialog.h"
#include "dialog-switch.h"
/* Color styles for normal and error dialogs */
int dialog_colors[4];
@ -687,16 +689,19 @@ dlg_execute_cmd (Dlg_head * h, unsigned long command)
h->ret_value = B_CANCEL;
dlg_stop (h);
break;
case CK_DialogPrevItem:
dlg_one_up (h);
break;
case CK_DialogNextItem:
dlg_one_down (h);
break;
case CK_DialogHelp:
interactive_display (NULL, h->help_ctx);
do_refresh ();
break;
case CK_DialogSuspend:
suspend_cmd ();
refresh_cmd ();
@ -704,6 +709,26 @@ dlg_execute_cmd (Dlg_head * h, unsigned long command)
case CK_DialogRefresh:
refresh_cmd ();
break;
case CK_DialogListCmd:
if (!h->modal)
dialog_switch_list ();
else
ret = MSG_NOT_HANDLED;
break;
case CK_DialogNextCmd:
if (!h->modal)
dialog_switch_next ();
else
ret = MSG_NOT_HANDLED;
break;
case CK_DialogPrevCmd:
if (!h->modal)
dialog_switch_prev ();
else
ret = MSG_NOT_HANDLED;
break;
default:
ret = MSG_NOT_HANDLED;
}
@ -885,12 +910,21 @@ init_dlg (Dlg_head * h)
if ((top_dlg != NULL) && ((Dlg_head *) top_dlg->data)->modal)
h->modal = TRUE;
/* add dialog to the stack */
top_dlg = g_list_prepend (top_dlg, h);
/* Initialize dialog manager and widgets */
h->callback (h, NULL, DLG_INIT, 0, NULL);
dlg_broadcast_msg (h, WIDGET_INIT, FALSE);
if (h->state == DLG_ACTIVE)
{
if (!h->modal)
dialog_switch_add (h);
h->callback (h, NULL, DLG_INIT, 0, NULL);
dlg_broadcast_msg (h, WIDGET_INIT, FALSE);
}
h->state = DLG_ACTIVE;
dlg_redraw (h);
@ -903,7 +937,6 @@ init_dlg (Dlg_head * h)
}
h->ret_value = 0;
h->state = DLG_ACTIVE;
}
void
@ -965,8 +998,12 @@ frontend_run_dlg (Dlg_head * h)
void
dlg_run_done (Dlg_head * h)
{
if (h->current != NULL)
if (h->state == DLG_CLOSED)
{
h->callback (h, (Widget *) h->current->data, DLG_END, 0, NULL);
if (!h->modal)
dialog_switch_remove (h);
}
top_dlg = g_list_remove (top_dlg, h);
}

Просмотреть файл

@ -1,5 +1,9 @@
/* Dialog box features module for the Midnight Commander
Copyright (C) 1994, 1995 Radek Doulik, Miguel de Icaza
Copyright (C) 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2007, 2009, 2010 Free Software Foundation
Authors: 1994, 1995 Radek Doulik, Miguel de Icaza
2009, 2010 Andrew Borodin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

Просмотреть файл

@ -3278,7 +3278,9 @@ diff_view (const char *file1, const char *file2, const char *label1, const char
*/
if (error == 0)
run_dlg (dview_dlg);
destroy_dlg (dview_dlg);
if ((error != 0) || (dview_dlg->state == DLG_CLOSED))
destroy_dlg (dview_dlg);
return error;
}

Просмотреть файл

@ -295,7 +295,8 @@ edit_file (const char *_file, int line)
run_dlg (edit_dlg);
destroy_dlg (edit_dlg);
if (edit_dlg->state == DLG_CLOSED)
destroy_dlg (edit_dlg);
return 1;
}

Просмотреть файл

@ -52,6 +52,7 @@
#include "charsets.h" /* get_codepage_index */
#include "selcodepage.h" /* do_set_codepage */
#endif
#include "dialog-switch.h"
#include "ext.h"
/* If set, we execute the file command to check the file type */
@ -321,7 +322,7 @@ exec_extension (const char *filename, const char *lc_data, int *move_dir, int st
if (changed_nroff_flag && !mcview_altered_nroff_flag)
mcview_default_nroff_flag = def_nroff_flag;
repaint_screen ();
dialog_switch_process_pending ();
}
else if (is_cd)
{

Просмотреть файл

@ -405,6 +405,9 @@ static name_keymap_t command_names[] = {
#ifdef USE_DIFF_VIEW
{ "CmdDiffView", CK_DiffViewCmd},
#endif
{ "CmdDialogList", CK_DialogListCmd },
{ "CmdDialogNext", CK_DialogNextCmd },
{ "CmdDialogPrev", CK_DialogPrevCmd },
/* panel */
{ "PanelChdirOtherPanel", CK_PanelChdirOtherPanel },
@ -944,9 +947,14 @@ const global_keymap_t default_main_map[] = {
{ ALT (','), CK_TogglePanelsSplit, "M-," },
{ XCTRL ('x'), CK_StartExtMap1, "C-x" },
/* Select/unselect group */
{ KEY_KP_ADD, CK_SelectCmd, "+" },
{ KEY_KP_SUBTRACT, CK_UnselectCmd, "-" },
{ ALT ('*'), CK_ReverseSelectionCmd, "*" },
{ KEY_KP_ADD, CK_SelectCmd, "+" },
{ KEY_KP_SUBTRACT, CK_UnselectCmd, "-" },
{ ALT ('*'), CK_ReverseSelectionCmd, "*" },
{ ALT ('`'), CK_DialogListCmd, "M-`"},
{ ALT ('}'), CK_DialogNextCmd, "M-}"},
{ ALT ('{'), CK_DialogPrevCmd, "M-{"},
{ 0, CK_Ignore_Key, "" }
};

Просмотреть файл

@ -90,6 +90,7 @@
#include "wtools.h"
#include "cmddef.h" /* CK_ cmd name const */
#include "user.h" /* user_file_menu_cmd() */
#include "dialog-switch.h"
#include "chmod.h"
#include "chown.h"
@ -756,6 +757,7 @@ create_command_menu (void)
#ifdef WITH_BACKGROUND
entries = g_list_append (entries, menu_entry_create (_("&Background jobs"), CK_JobsCmd));
#endif
entries = g_list_append (entries, menu_entry_create (_("Screen lis&t"), CK_DialogListCmd));
entries = g_list_append (entries, menu_separator_create ());
#ifdef USE_EXT2FSLIB
entries =
@ -1214,6 +1216,9 @@ midnight_execute_cmd (Widget * sender, unsigned long command)
case CK_DeleteCmd:
delete_cmd ();
break;
case CK_DialogListCmd:
dialog_switch_list ();
break;
#ifdef USE_DIFF_VIEW
case CK_DiffViewCmd:
diff_view_cmd ();

Просмотреть файл

@ -47,9 +47,8 @@
#include "setup.h"
#include "history.h"
/* For the simple listbox manager */
#include "dialog.h"
#include "dialog-switch.h"
#include "widget.h"
#include "wtools.h"
@ -775,7 +774,10 @@ execute_menu_command (WEdit * edit_widget, const char *commands)
fclose (cmd_file);
chmod (file_name, S_IRWXU);
if (run_view)
{
mcview_viewer (file_name, NULL, 0);
dialog_switch_process_pending ();
}
else
{
/* execute the command indirectly to allow execution even

Просмотреть файл

@ -257,6 +257,7 @@ mcview_viewer (const char *command, const char *file, int start_line)
view_dlg->get_title = mcview_get_title;
succeeded = mcview_load (lc_mcview, command, file, start_line);
if (succeeded)
{
run_dlg (view_dlg);
@ -269,7 +270,9 @@ mcview_viewer (const char *command, const char *file, int start_line)
view_dlg->state = DLG_CLOSED;
ret = MCVIEW_EXIT_FAILURE;
}
destroy_dlg (view_dlg);
if (view_dlg->state == DLG_CLOSED)
destroy_dlg (view_dlg);
return ret;
}