Fix #880: Optimize file loading when looking for duplicates
[geeqie.git] / src / dupe.h
1 /*
2  * Copyright (C) 2004 John Ellis
3  * Copyright (C) 2008 - 2016 The Geeqie Team
4  *
5  * Author: John Ellis
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifndef DUPE_H
23 #define DUPE_H
24
25 #include "similar.h"
26
27 /* match methods */
28 typedef enum
29 {
30         DUPE_MATCH_NONE = 0,
31         DUPE_MATCH_NAME = 1 << 0,
32         DUPE_MATCH_SIZE = 1 << 1,
33         DUPE_MATCH_DATE = 1 << 2,
34         DUPE_MATCH_DIM  = 1 << 3,       /* image dimensions */
35         DUPE_MATCH_SUM  = 1 << 4,       /* MD5sum */
36         DUPE_MATCH_PATH = 1 << 5,
37         DUPE_MATCH_SIM_HIGH = 1 << 6,   /* similarity */
38         DUPE_MATCH_SIM_MED  = 1 << 7,
39         DUPE_MATCH_SIM_LOW  = 1 << 8,
40         DUPE_MATCH_SIM_CUSTOM = 1 << 9,
41         DUPE_MATCH_NAME_CI = 1 << 10,   /* same as name, but case insensitive */
42         DUPE_MATCH_NAME_CONTENT = 1 << 11,      /* same name, but different content */
43         DUPE_MATCH_NAME_CI_CONTENT = 1 << 12,   /* same name - case insensitive, but different content */
44         DUPE_MATCH_ALL = 1 << 13 /* N.B. this is used as a clamp value in rcfile.c */
45 } DupeMatchType;
46
47 typedef enum
48 {
49         DUPE_SELECT_NONE,
50         DUPE_SELECT_GROUP1,
51         DUPE_SELECT_GROUP2
52 } DupeSelectType;
53
54 typedef struct _DupeItem DupeItem;
55 struct _DupeItem
56 {
57         CollectionData *collection;     /* NULL if from DupeWindow->files */
58         CollectInfo *info;
59
60         FileData *fd;
61
62         gchar *md5sum;
63         gint width;
64         gint height;
65         gint dimensions; /* Computed as (di->width << 16) + di->height */
66
67         ImageSimilarityData *simd;
68
69         /* thumb */
70         GdkPixbuf *pixbuf;
71
72         GList *group;                   /* List of match data */
73         gdouble group_rank;
74
75         gint second;
76 };
77
78 typedef struct _DupeMatch DupeMatch;
79 struct _DupeMatch
80 {
81         DupeItem *di;
82         gdouble rank;
83 };
84
85 typedef struct _DupeWindow DupeWindow;
86 struct _DupeWindow
87 {
88         GList *list;                    /* dropped files (DupeItem) */
89         GList *dupes;                   /* list of dupes (DupeItem, grouping the DupeMatches) */
90         DupeMatchType match_mask;       /* mask of things to check for match */
91
92         GtkWidget *window;
93         GtkWidget *table;
94         GtkWidget *listview;
95         GtkWidget *combo;
96         GtkWidget *status_label;
97         GtkWidget *extra_label;
98         GtkWidget *button_thumbs;
99         GtkWidget *button_rotation_invariant;
100         GtkWidget *custom_threshold;
101         GList *add_files_queue;
102         guint add_files_queue_id;
103         GHashTable *list_cache; /* Caches the DupeItems of all items in list */
104         GHashTable *second_list_cache; /* Caches the DupeItems of all items in second_list */
105         GtkWidget *controls_box;
106
107         gboolean show_thumbs;
108
109         guint idle_id; /* event source id */
110         GList *working;
111         gint setup_done;
112         gint setup_count; /* length of set1 or if 2 sets, total length of both */
113         gint setup_n;                   /* these are merely for speed optimization */
114         GList *setup_point;             /* ditto */
115         DupeMatchType setup_mask;       /* ditto */
116         guint64 setup_time;
117         guint64 setup_time_count;
118
119         DupeItem *click_item;           /* for popup menu */
120
121         ThumbLoader *thumb_loader;
122         DupeItem *thumb_item;
123
124         ImageLoader *img_loader;
125
126         GtkTreeSortable *sortable;
127         gint set_count;
128
129         /* second set comparison stuff */
130
131         gboolean second_set;            /* second set enabled ? */
132         GList *second_list;             /* second set dropped files */
133         gboolean second_drop;           /* drop is on second set */
134
135         GtkWidget *second_vbox;         /* box of second widgets */
136         GtkWidget *second_listview;
137         GtkWidget *second_status_label;
138
139         gboolean color_frozen;
140 };
141
142
143 DupeWindow *dupe_window_new(void);
144
145 void dupe_window_clear(DupeWindow *dw);
146 void dupe_window_close(DupeWindow *dw);
147
148 void dupe_window_add_collection(DupeWindow *dw, CollectionData *collection);
149 void dupe_window_add_files(DupeWindow *dw, GList *list, gboolean recurse);
150
151 /* cell max with/height hack utility */
152 void cell_renderer_height_override(GtkCellRenderer *renderer);
153
154
155 #endif
156 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */