2 Load and show history of edited and viewed files
5 Free Software Foundation, Inc.
8 Andrew Borodin <aborodin@vmail.ru>, 2019.
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include <stdio.h> /* file functions */
30 #include "lib/global.h"
32 #include "lib/fileloc.h" /* MC_FILEPOS_FILE */
33 #include "lib/mcconfig.h" /* mc_config_get_full_path() */
34 #include "lib/strutil.h" /* str_term_width1() */
35 #include "lib/util.h" /* backup functions */
37 #include "file_history.h"
39 /*** global variables ****************************************************************************/
41 /*** file scope macro definitions ****************************************************************/
43 #define TMP_SUFFIX ".tmp"
45 /*** file scope type declarations ****************************************************************/
47 typedef struct file_history_data_t
51 } file_history_data_t
;
53 /*** file scope variables ************************************************************************/
55 /* --------------------------------------------------------------------------------------------- */
56 /*** file scope functions ************************************************************************/
57 /* --------------------------------------------------------------------------------------------- */
60 file_history_list_read (void)
64 char buf
[MC_MAXPATHLEN
+ 100];
65 GList
*file_list
= NULL
;
67 /* open file with positions */
68 fn
= mc_config_get_full_path (MC_FILEPOS_FILE
);
77 while (fgets (buf
, sizeof (buf
), f
) != NULL
)
80 file_history_data_t
*fhd
;
83 s
= strrchr (buf
, ' ');
84 /* FIXME: saved file position info is present in filepos file */
85 fhd
= g_new (file_history_data_t
, 1);
86 fhd
->file_name
= g_strndup (buf
, s
- buf
);
88 fhd
->file_pos
= g_strndup (s
+ 1, len
- 1); /* ignore '\n' */
89 file_list
= g_list_prepend (file_list
, fhd
);
97 /* --------------------------------------------------------------------------------------------- */
100 file_history_list_write (const GList
* file_list
)
104 gboolean write_error
= FALSE
;
106 fn
= mc_config_get_full_path (MC_FILEPOS_FILE
);
110 mc_util_make_backup_if_possible (fn
, TMP_SUFFIX
);
117 s
= g_string_sized_new (128);
119 for (; file_list
!= NULL
&& !write_error
; file_list
= g_list_next (file_list
))
121 file_history_data_t
*fhd
= (file_history_data_t
*) file_list
->data
;
123 g_string_append (s
, fhd
->file_name
);
124 if (fhd
->file_pos
!= NULL
)
126 g_string_append_c (s
, ' ');
127 g_string_append (s
, fhd
->file_pos
);
130 write_error
= (fprintf (f
, "%s\n", s
->str
) < 0);
131 g_string_truncate (s
, 0);
134 g_string_free (s
, TRUE
);
140 mc_util_restore_from_backup_if_possible (fn
, TMP_SUFFIX
);
142 mc_util_unlink_backup_if_possible (fn
, TMP_SUFFIX
);
147 /* --------------------------------------------------------------------------------------------- */
150 file_history_create_item (history_descriptor_t
* hd
, void *data
)
152 file_history_data_t
*fhd
= (file_history_data_t
*) data
;
155 width
= str_term_width1 (fhd
->file_name
);
156 hd
->max_width
= MAX (width
, hd
->max_width
);
158 listbox_add_item (hd
->listbox
, LISTBOX_APPEND_AT_END
, 0, fhd
->file_name
, fhd
->file_pos
, TRUE
);
159 /* fhd->file_pos is not copied, NULLize it to prevent double free */
160 fhd
->file_pos
= NULL
;
163 /* --------------------------------------------------------------------------------------------- */
166 file_history_release_item (history_descriptor_t
* hd
, WLEntry
* le
)
168 file_history_data_t
*fhd
;
172 fhd
= g_new (file_history_data_t
, 1);
173 fhd
->file_name
= le
->text
;
175 fhd
->file_pos
= (char *) le
->data
;
181 /* --------------------------------------------------------------------------------------------- */
184 file_history_free_item (void *data
)
186 file_history_data_t
*fhd
= (file_history_data_t
*) data
;
188 g_free (fhd
->file_name
);
189 g_free (fhd
->file_pos
);
193 /* --------------------------------------------------------------------------------------------- */
194 /*** public functions ****************************************************************************/
195 /* --------------------------------------------------------------------------------------------- */
198 * Show file history and return the selected file
200 * @param w widget used for positioning of history window
201 * @param action to do with file (edit, view, etc)
203 * @return name of selected file, A newly allocated string.
206 show_file_history (const Widget
* w
, int *action
)
210 history_descriptor_t hd
;
212 file_list
= file_history_list_read ();
213 if (file_list
== NULL
)
216 len
= g_list_length (file_list
);
218 file_list
= g_list_last (file_list
);
220 history_descriptor_init (&hd
, w
->y
, w
->x
, file_list
, 0);
221 /* redefine list-specific functions */
222 hd
.create
= file_history_create_item
;
223 hd
.release
= file_history_release_item
;
224 hd
.free
= file_history_free_item
;
228 hd
.list
= g_list_first (hd
.list
);
230 /* Has history cleaned up or not? */
231 if (len
!= g_list_length (hd
.list
))
232 file_history_list_write (hd
.list
);
234 g_list_free_full (hd
.list
, (GDestroyNotify
) file_history_free_item
);
241 /* --------------------------------------------------------------------------------------------- */