root/src/filemanager/listmode.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. select_new_item
  2. bplus_cback
  3. bminus_cback
  4. badd_cback
  5. bremove_cback
  6. init_listmode
  7. listmode_done
  8. collect_new_format
  9. listmode_edit

   1 /*
   2    Directory panel listing format editor -- for the Midnight Commander
   3 
   4    Copyright (C) 1994-2025
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Radek Doulik, 1994
   9    Janne Kukonlehto, 1995
  10 
  11    This file is part of the Midnight Commander.
  12 
  13    The Midnight Commander is free software: you can redistribute it
  14    and/or modify it under the terms of the GNU General Public License as
  15    published by the Free Software Foundation, either version 3 of the License,
  16    or (at your option) any later version.
  17 
  18    The Midnight Commander is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22 
  23    You should have received a copy of the GNU General Public License
  24    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  25  */
  26 
  27 /** \file listmode.c
  28  *  \brief Source: directory panel listing format editor
  29  */
  30 
  31 #include <config.h>
  32 
  33 #ifdef LISTMODE_EDITOR
  34 
  35 #include <stdio.h>
  36 #include <string.h>
  37 
  38 #include <sys/types.h>
  39 #include <sys/stat.h>
  40 #include <unistd.h>
  41 
  42 #include "lib/global.h"
  43 #include "lib/widget.h"
  44 
  45 #include "lib/tty/tty.h"
  46 #include "lib/tty/key.h"
  47 #include "lib/skin/skin.h"
  48 
  49 /* Needed for the extern declarations of integer parameters */
  50 #include "dir.h"
  51 #include "panel.h"  // Needed for the externs
  52 #include "file.h"
  53 #include "listmode.h"
  54 
  55 /*** global variables ****************************************************************************/
  56 
  57 /*** file scope macro definitions ****************************************************************/
  58 
  59 #define UX       5
  60 #define UY       2
  61 
  62 #define BX       5
  63 #define BY       18
  64 
  65 #define B_ADD    B_USER
  66 #define B_REMOVE (B_USER + 1)
  67 
  68 #define B_PLUS   B_USER
  69 #define B_MINUS  (B_USER + 1)
  70 
  71 /*** file scope type declarations ****************************************************************/
  72 
  73 struct listmode_button
  74 {
  75     int ret_cmd, flags, y, x;
  76     char *text;
  77     bcback callback;
  78 };
  79 
  80 struct listmode_label
  81 {
  82     int y, x;
  83     char *text;
  84 };
  85 
  86 /*** forward declarations (file scope functions) *************************************************/
  87 
  88 /*** file scope variables ************************************************************************/
  89 
  90 static WListbox *l_listmode;
  91 
  92 static WLabel *pname;
  93 
  94 static char *listmode_section = "[Listing format edit]";
  95 
  96 static char *s_genwidth[2] = {
  97     "Half width",
  98     "Full width",
  99 };
 100 
 101 static WRadio *radio_genwidth;
 102 static char *s_columns[2] = {
 103     "One column",
 104     "Two columns",
 105 };
 106 
 107 static WRadio *radio_columns;
 108 static char *s_justify[3] = {
 109     "Left justified",
 110     "Default justification",
 111     "Right justified",
 112 };
 113 
 114 static WRadio *radio_justify;
 115 static char *s_itemwidth[3] = {
 116     "Free width",
 117     "Fixed width",
 118     "Growable width",
 119 };
 120 
 121 static WRadio *radio_itemwidth;
 122 
 123 /* --------------------------------------------------------------------------------------------- */
 124 /*** file scope functions ************************************************************************/
 125 /* --------------------------------------------------------------------------------------------- */
 126 
 127 static char *
 128 select_new_item (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 129 {
 130     char **possible_items;
 131     char *ret = NULL;
 132     int i;
 133     Listbox *mylistbox;
 134 
 135     possible_items = panel_get_user_possible_fields (NULL);
 136 
 137     mylistbox = listbox_window_new (20, 12, "Add listing format item", listmode_section);
 138     for (i = 0; possible_items[i]; i++)
 139     {
 140         listbox_add_item (mylistbox->list, LISTBOX_APPEND_AT_END, 0, possible_items[i], NULL,
 141                           FALSE);
 142     }
 143 
 144     i = listbox_run (mylistbox);
 145     if (i >= 0)
 146         ret = g_strdup (possible_items[i]);
 147 
 148     g_strfreev (possible_items);
 149     return ret;
 150 }
 151 
 152 /* --------------------------------------------------------------------------------------------- */
 153 
 154 static int
 155 bplus_cback (int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 156 {
 157     return 0;
 158 }
 159 
 160 /* --------------------------------------------------------------------------------------------- */
 161 
 162 static int
 163 bminus_cback (int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 164 {
 165     return 0;
 166 }
 167 
 168 /* --------------------------------------------------------------------------------------------- */
 169 
 170 static int
 171 badd_cback (int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 172 {
 173     char *s = select_new_item ();
 174     if (s)
 175     {
 176         listbox_add_item (l_listmode, LISTBOX_APPEND_AT_END, 0, s, NULL, FALSE);
 177         g_free (s);
 178     }
 179     return 0;
 180 }
 181 
 182 /* --------------------------------------------------------------------------------------------- */
 183 
 184 static int
 185 bremove_cback (int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 186 {
 187     listbox_remove_current (l_listmode);
 188     return 0;
 189 }
 190 
 191 /* --------------------------------------------------------------------------------------------- */
 192 
 193 static WDialog *
 194 init_listmode (char *oldlistformat)
     /* [previous][next][first][last][top][bottom][index][help]  */
 195 {
 196     int i;
 197     char *s;
 198     int format_width = 0;
 199     int format_columns = 0;
 200     WDialog *listmode_dlg;
 201 
 202     static struct listmode_label listmode_labels[] = { { UY + 13, UX + 22, "Item width:" } };
 203 
 204     static struct listmode_button listmode_but[] = {
 205         { B_CANCEL, NORMAL_BUTTON, BY, BX + 53, "&Cancel", NULL },
 206         { B_ADD, NORMAL_BUTTON, BY, BX + 22, "&Add item", badd_cback },
 207         { B_REMOVE, NORMAL_BUTTON, BY, BX + 10, "&Remove", bremove_cback },
 208         { B_ENTER, DEFPUSH_BUTTON, BY, BX, "&OK", NULL },
 209         { B_PLUS, NARROW_BUTTON, UY + 13, UX + 37, "&+", bplus_cback },
 210         { B_MINUS, NARROW_BUTTON, UY + 13, UX + 34, "&-", bminus_cback },
 211     };
 212 
 213     do_refresh ();
 214 
 215     listmode_dlg = dlg_create (TRUE, 0, 0, 22, 74, WPOS_CENTER, FALSE, dialog_colors, NULL, NULL,
 216                                listmode_section, "Listing format edit");
 217 
 218     add_widget (listmode_dlg, groupbox_new (UY, UX, 4, 63, "General options"));
 219     add_widget (listmode_dlg, groupbox_new (UY + 4, UX, 11, 18, "Items"));
 220     add_widget (listmode_dlg, groupbox_new (UY + 4, UX + 20, 11, 43, "Item options"));
 221 
 222     for (i = 0; i < sizeof (listmode_but) / sizeof (struct listmode_button); i++)
 223         add_widget (listmode_dlg,
 224                     button_new (listmode_but[i].y, listmode_but[i].x, listmode_but[i].ret_cmd,
 225                                 listmode_but[i].flags, listmode_but[i].text,
 226                                 listmode_but[i].callback));
 227 
 228     // We add the labels.
 229     for (i = 0; i < sizeof (listmode_labels) / sizeof (struct listmode_label); i++)
 230     {
 231         pname = label_new (listmode_labels[i].y, listmode_labels[i].x, listmode_labels[i].text);
 232         add_widget (listmode_dlg, pname);
 233     }
 234 
 235     radio_itemwidth = radio_new (UY + 9, UX + 22, 3, s_itemwidth);
 236     add_widget (listmode_dlg, radio_itemwidth);
 237     radio_itemwidth = 0;
 238     radio_justify = radio_new (UY + 5, UX + 22, 3, s_justify);
 239     add_widget (listmode_dlg, radio_justify);
 240     radio_justify->sel = 1;
 241 
 242     // get new listbox
 243     l_listmode = listbox_new (UY + 5, UX + 1, 9, 16, FALSE, NULL);
 244 
 245     if (strncmp (oldlistformat, "full ", 5) == 0)
 246     {
 247         format_width = 1;
 248         oldlistformat += 5;
 249     }
 250     if (strncmp (oldlistformat, "half ", 5) == 0)
 251     {
 252         oldlistformat += 5;
 253     }
 254     if (strncmp (oldlistformat, "2 ", 2) == 0)
 255     {
 256         format_columns = 1;
 257         oldlistformat += 2;
 258     }
 259     if (strncmp (oldlistformat, "1 ", 2) == 0)
 260     {
 261         oldlistformat += 2;
 262     }
 263     s = strtok (oldlistformat, ",");
 264 
 265     while (s)
 266     {
 267         listbox_add_item (l_listmode, LISTBOX_APPEND_AT_END, 0, s, NULL, FALSE);
 268         s = strtok (NULL, ",");
 269     }
 270 
 271     // add listbox to the dialogs
 272     add_widget (listmode_dlg, l_listmode);
 273 
 274     radio_columns = radio_new (UY + 1, UX + 32, 2, s_columns);
 275     add_widget (listmode_dlg, radio_columns);
 276     radio_columns->sel = format_columns;
 277     radio_genwidth = radio_new (UY + 1, UX + 2, 2, s_genwidth);
 278     add_widget (listmode_dlg, radio_genwidth);
 279     radio_genwidth->sel = format_width;
 280 
 281     return listmode_dlg;
 282 }
 283 
 284 /* --------------------------------------------------------------------------------------------- */
 285 
 286 static void
 287 listmode_done (WDialog *h)
     /* [previous][next][first][last][top][bottom][index][help]  */
 288 {
 289     widget_destroy (WIDGET (h));
 290     if (0)
 291         update_panels (UP_OPTIMIZE, UP_KEEPSEL);
 292     repaint_screen ();
 293 }
 294 
 295 /* --------------------------------------------------------------------------------------------- */
 296 
 297 static char *
 298 collect_new_format (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 299 {
 300     char *newformat;
 301     int i;
 302     char *last;
 303     char *text, *extra;
 304 
 305     newformat = g_malloc (1024);
 306     if (radio_genwidth->sel)
 307         strcpy (newformat, "full ");
 308     else
 309         strcpy (newformat, "half ");
 310     if (radio_columns->sel)
 311         strcat (newformat, "2 ");
 312     last = NULL;
 313     for (i = 0;; i++)
 314     {
 315         listbox_set_current (l_listmode, i);
 316         listbox_get_current (l_listmode, &text, &extra);
 317         if (text == last)
 318             break;
 319         if (last != NULL)
 320             strcat (newformat, ",");
 321         strcat (newformat, text);
 322         last = text;
 323     }
 324     return newformat;
 325 }
 326 
 327 /* --------------------------------------------------------------------------------------------- */
 328 /*** public functions ****************************************************************************/
 329 /* --------------------------------------------------------------------------------------------- */
 330 
 331 /** Return new format or NULL if the user cancelled the dialog */
 332 char *
 333 listmode_edit (char *oldlistformat)
     /* [previous][next][first][last][top][bottom][index][help]  */
 334 {
 335     char *newformat = NULL;
 336     char *s;
 337     WDialog *listmode_dlg;
 338 
 339     s = g_strdup (oldlistformat);
 340     listmode_dlg = init_listmode (s);
 341     g_free (s);
 342 
 343     if (dlg_run (listmode_dlg) == B_ENTER)
 344     {
 345         newformat = collect_new_format ();
 346     }
 347 
 348     listmode_done (listmode_dlg);
 349     return newformat;
 350 }
 351 
 352 /* --------------------------------------------------------------------------------------------- */
 353 
 354 #endif

/* [previous][next][first][last][top][bottom][index][help]  */