2018-07-25 16:44:04 +02:00
|
|
|
/*
|
|
|
|
* GDSII-Converter
|
|
|
|
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
|
|
|
|
*
|
|
|
|
* This file is part of GDSII-Converter.
|
|
|
|
*
|
|
|
|
* GDSII-Converter is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* GDSII-Converter 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 GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file tree-store.h
|
|
|
|
* @brief Tree store implementation
|
|
|
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @addtogroup MainApplication
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2018-05-22 12:59:28 +02:00
|
|
|
#include "tree-store.h"
|
|
|
|
#include "lib-cell-renderer.h"
|
2018-05-22 16:17:14 +02:00
|
|
|
#include "../gds-parser/gds-types.h"
|
2018-05-22 12:59:28 +02:00
|
|
|
|
2018-07-25 16:44:04 +02:00
|
|
|
/**
|
|
|
|
* @brief this function olny allows cells to be selected
|
|
|
|
* @param selection
|
|
|
|
* @param model
|
|
|
|
* @param path
|
|
|
|
* @param path_currently_selected
|
|
|
|
* @param data
|
|
|
|
* @return TRUE if element is selectable, FALSE if not
|
|
|
|
*/
|
2018-05-22 13:00:50 +02:00
|
|
|
static gboolean tree_sel_func(GtkTreeSelection *selection,
|
|
|
|
GtkTreeModel *model,
|
|
|
|
GtkTreePath *path,
|
|
|
|
gboolean path_currently_selected,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
struct gds_cell *cell;
|
2019-03-05 21:02:57 +01:00
|
|
|
unsigned int error_level;
|
|
|
|
gboolean ret = FALSE;
|
2018-05-22 13:00:50 +02:00
|
|
|
|
|
|
|
gtk_tree_model_get_iter(model, &iter, path);
|
2019-03-05 21:02:57 +01:00
|
|
|
gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1);
|
2018-05-22 13:00:50 +02:00
|
|
|
|
2019-03-05 21:02:57 +01:00
|
|
|
/* Allow only rows with _valid_ cell to be selected */
|
|
|
|
if (cell) {
|
|
|
|
/* Cell available. Check if it passed the critical checks */
|
|
|
|
if (!(error_level & LIB_CELL_RENDERER_ERROR_ERR))
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2018-05-22 13:00:50 +02:00
|
|
|
}
|
|
|
|
|
2019-02-04 20:02:10 +01:00
|
|
|
/**
|
2019-02-05 20:38:52 +01:00
|
|
|
* @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
|
2019-02-04 20:02:10 +01:00
|
|
|
* @param model Tree model
|
2019-02-05 20:38:52 +01:00
|
|
|
* @param iter Current element / iter in Model to check
|
|
|
|
* @param data Data. Set to static stores variable
|
|
|
|
* @return TRUE if visible, else FALSE
|
|
|
|
* @note TODO: Maybe implement Damerau-Levenshtein distance matching
|
2019-02-04 20:02:10 +01:00
|
|
|
*/
|
2019-02-05 20:38:52 +01:00
|
|
|
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
|
2019-02-04 20:02:10 +01:00
|
|
|
{
|
2019-02-05 20:38:52 +01:00
|
|
|
struct tree_stores *stores = (struct tree_stores *)data;
|
2019-02-04 20:02:10 +01:00
|
|
|
struct gds_cell *cell;
|
|
|
|
struct gds_library *lib;
|
2019-02-05 20:38:52 +01:00
|
|
|
gboolean result = FALSE;
|
|
|
|
const char *search_string;
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
if (!model || !iter || !stores)
|
|
|
|
goto exit_filter;
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
if (lib) {
|
|
|
|
result = TRUE;
|
|
|
|
goto exit_filter;
|
2019-02-04 20:02:10 +01:00
|
|
|
}
|
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
if (!cell)
|
|
|
|
goto exit_filter;
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
search_string = gtk_entry_get_text(stores->search_entry);
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
/* Show all, if field is empty */
|
|
|
|
if (!strlen(search_string))
|
|
|
|
result = TRUE;
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
if (strstr(cell->name, search_string))
|
|
|
|
result = TRUE;
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
gtk_tree_view_expand_all(stores->base_tree_view);
|
2019-02-04 20:02:10 +01:00
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
exit_filter:
|
2019-02-04 20:02:10 +01:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
static void change_filter(GtkWidget *entry, gpointer data)
|
|
|
|
{
|
|
|
|
struct tree_stores *stores = (struct tree_stores *)data;
|
|
|
|
gtk_tree_model_filter_refilter(stores->filter);
|
|
|
|
}
|
|
|
|
|
2018-07-25 16:44:04 +02:00
|
|
|
/**
|
|
|
|
* @brief Setup a GtkTreeView with the necessary columns
|
|
|
|
* @param view Tree view to set up
|
2019-02-04 20:02:10 +01:00
|
|
|
* @param search_entry Entry field for search
|
2019-02-05 19:44:29 +01:00
|
|
|
* @return Tree stores for storing data inside the GtkTreeView
|
2018-07-25 16:44:04 +02:00
|
|
|
*/
|
2019-02-05 19:44:29 +01:00
|
|
|
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry)
|
2018-05-22 12:59:28 +02:00
|
|
|
{
|
2019-02-05 19:44:29 +01:00
|
|
|
static struct tree_stores stores;
|
2018-05-22 12:59:28 +02:00
|
|
|
GtkCellRenderer *render_dates;
|
|
|
|
GtkCellRenderer *render_cell;
|
|
|
|
GtkCellRenderer *render_lib;
|
|
|
|
GtkTreeViewColumn *column;
|
|
|
|
|
2019-02-05 20:38:52 +01:00
|
|
|
stores.base_tree_view = view;
|
|
|
|
stores.search_entry = search_entry;
|
|
|
|
|
2019-03-05 20:50:54 +01:00
|
|
|
stores.base_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
|
2019-02-05 20:38:52 +01:00
|
|
|
|
|
|
|
/* Searching */
|
|
|
|
if (search_entry) {
|
|
|
|
stores.filter = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(GTK_TREE_MODEL(stores.base_store), NULL));
|
|
|
|
gtk_tree_model_filter_set_visible_func (stores.filter,
|
|
|
|
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
|
|
|
|
&stores, NULL);
|
|
|
|
g_signal_connect(GTK_SEARCH_ENTRY(search_entry), "search-changed", G_CALLBACK(change_filter), &stores);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_tree_view_set_model(view, GTK_TREE_MODEL(stores.filter));
|
2018-05-22 12:59:28 +02:00
|
|
|
|
|
|
|
render_dates = gtk_cell_renderer_text_new();
|
|
|
|
render_cell = lib_cell_renderer_new();
|
|
|
|
render_lib = lib_cell_renderer_new();
|
|
|
|
|
|
|
|
column = gtk_tree_view_column_new_with_attributes("Library", render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
|
|
|
|
gtk_tree_view_append_column(view, column);
|
|
|
|
|
2019-03-05 20:50:54 +01:00
|
|
|
column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "gds-cell", CELL_SEL_CELL,
|
|
|
|
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
|
2018-05-22 12:59:28 +02:00
|
|
|
gtk_tree_view_append_column(view, column);
|
|
|
|
|
|
|
|
column = gtk_tree_view_column_new_with_attributes("Mod. Date", render_dates, "text", CELL_SEL_MODDATE, NULL);
|
|
|
|
gtk_tree_view_append_column(view, column);
|
|
|
|
|
|
|
|
column = gtk_tree_view_column_new_with_attributes("Acc. Date", render_dates, "text", CELL_SEL_ACCESSDATE, NULL);
|
|
|
|
gtk_tree_view_append_column(view, column);
|
|
|
|
|
2018-05-22 13:00:50 +02:00
|
|
|
/* Callback for selection
|
|
|
|
* This prevents selecting a library */
|
|
|
|
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(view), tree_sel_func, NULL, NULL);
|
|
|
|
|
2019-02-05 19:44:29 +01:00
|
|
|
return &stores;
|
2018-05-22 12:59:28 +02:00
|
|
|
}
|
2018-07-25 16:44:04 +02:00
|
|
|
/** @} */
|