/* * Copyright (C) 2012 - Juan Ferrer Toribio * * 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 3 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, see . */ #include "db-iterator.h" #include "db-model-holder.h" #define IS_READY(self) (self->model && db_model_is_ready (self->model)) static void db_iterator_model_holder_init (DbModelHolderInterface * iface); /** * SECTION:db-iterator * @short_description: manages a iterator with its events * @title: DbIterator * * The #DbIterator manages a connection with a data base. The function * db_iterator_new() creates a new #DbIterator. */ G_DEFINE_TYPE_WITH_CODE (DbIterator, db_iterator, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (DB_TYPE_MODEL_HOLDER, db_iterator_model_holder_init) ); enum { ITER_CHANGED ,DATA_CHANGED ,ROW_NUM_CHANGED ,STATUS_CHANGED ,OPERATIONS_DONE ,LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; /** * db_iterator_new: * @model: the #DbModel used by iterator. * * Creates a new #DbIterator. * * Return value: a #DbIterator. **/ DbIterator * db_iterator_new (DbModel * model) { return g_object_new (DB_TYPE_ITERATOR, "model", model, NULL); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void db_iterator_unref_param (DbIterator * self, DbParam * param) { self->params = g_list_remove (self->params, param); } /* * #DbIterator instances call this function every time line in * the model is changed. */ static void db_iterator_row_num_changed (DbIterator * self) { if (self->row_selected) self->row = db_model_get_path (self->model, &self->iter); else if (self->selected || !self->remember_selection) self->row = -1; g_signal_emit (self, signals[ROW_NUM_CHANGED], 0); } /* * #DbIterator instances call this function every time the data of the params * mustbe updated. */ static void db_iterator_iter_changed (DbIterator * self) { db_iterator_row_num_changed (self); g_signal_emit (self, signals[ITER_CHANGED], 0); } static void db_iterator_unselect (DbIterator * self) { if (self->selected) { g_hash_table_destroy (self->selected); self->selected = NULL; } } static void db_iterator_set_iter (DbIterator * self, DbIter * iter) { if (iter) { self->row_selected = TRUE; self->iter = *iter; db_iterator_iter_changed (self); } else if (self->row_selected) { self->row_selected = FALSE; db_iterator_iter_changed (self); } db_iterator_unselect (self); } /* * Function called when row is inserted on the model. */ static void db_iterator_on_model_line_inserted (DbModel * model, DbIter * iter, DbIterator * self) { g_signal_emit (self, signals[DATA_CHANGED], 0); } /* * Function called when row is updated on the model. */ static void db_iterator_on_model_line_updated_after (DbModel * model, DbIter * iter, DbIterator * self) { if (self->row_selected && db_iter_compare (iter, &self->iter)) db_iterator_iter_changed (self); g_signal_emit (self, signals[DATA_CHANGED], 0); } /* * Function called when row is deleted on the model. */ static void db_iterator_on_model_line_deleted (DbModel * model, gint row, DbIterator * self) { if (self->row_selected && row == self->row) { DbIter iter; if (db_model_get_iter (model, &iter, row + 1) || db_model_get_iter (model, &iter, row - 1)) db_iterator_set_iter (self, &iter); else db_iterator_set_iter (self, NULL); } } static void db_iterator_on_model_line_deleted_after (DbModel * model, gint row, DbIterator * self) { if (self->row_selected || self->selected) db_iterator_row_num_changed (self); g_signal_emit (self, signals[DATA_CHANGED], 0); } /* * Function called when model rows are reordered. */ static void db_iterator_on_model_lines_reordered (DbModel * model, gint column, gint * new_order, DbIterator * self) { if (self->row_selected || self->selected) db_iterator_row_num_changed (self); } /* * Function called when model status changes. */ static void db_iterator_on_model_status_changed (DbModel * model, DbModelStatus status, DbIterator * self) { if (status == DB_MODEL_STATUS_READY) { DbIter iter; gint nrows = db_model_get_nrows (model); g_signal_emit (self, signals[STATUS_CHANGED], 0, IS_READY(self)); if (self->row >= 0 && self->row < nrows && db_model_get_iter (model, &iter, self->row)) db_iterator_set_iter (self, &iter); else db_iterator_set_iter (self, NULL); } else { db_iterator_set_iter (self, NULL); g_signal_emit (self, signals[STATUS_CHANGED], 0, IS_READY(self)); } } /* * Function called when model operations are done. */ static void db_iterator_on_model_operations_done (DbModel * model, DbIterator * self) { g_signal_emit (self, signals[OPERATIONS_DONE], 0); } static void db_iterator_set_model_mode (DbIterator * self) { if (self->mode == DB_ITERATOR_MODE_ON_CHANGE) db_model_set_mode (self->model, DB_MODEL_MODE_ON_CHANGE); else db_model_set_mode (self->model, DB_MODEL_MODE_ON_DEMAND); } /* * Sets the model used as a data source by iterator. */ static void db_iterator_set_model (DbIterator * self, DbModel * model) { if (!model) return; if (!self->model) { self->model = g_object_ref (model); g_object_connect (self->model ,"signal::lines-reordered", db_iterator_on_model_lines_reordered, self ,"signal::line-inserted", db_iterator_on_model_line_inserted, self ,"signal-after::line-updated", db_iterator_on_model_line_updated_after, self ,"signal::line-deleted", db_iterator_on_model_line_deleted, self ,"signal-after::line-deleted", db_iterator_on_model_line_deleted_after, self ,"signal::status-changed", db_iterator_on_model_status_changed, self ,"signal::operations-done", db_iterator_on_model_operations_done, self ,NULL ); db_iterator_set_model_mode (self); db_iterator_on_model_status_changed (model, db_model_get_status (model), self); } else g_warning ("DbIterator: Can't reassign the 'model' property"); } /* * Check if the iterator has any selected row, otherwise issues a message. */ static gboolean db_iterator_check_row_selected (DbIterator * self) { if (self->row_selected) return TRUE; g_warning ("DbIterator: Row not selected"); return FALSE; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public /** * db_iterator_get_row: * @self: a #DbIterator * * Gets the selected row number. * * Return value: the row number **/ gint db_iterator_get_row (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), -1); if (self->row_selected) return self->row; else return -1; } /** * db_iterator_get_model: * @self: a #DbIterator * * Gets the model used as a data source by iterator. * * Return value: (transfer none): the #DbModel **/ DbModel * db_iterator_get_model (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), NULL); return self->model; } /** * db_iterator_is_ready: * @self: a #DbIterator * * Gets if the iterator is ready. * * Return value: %TRUE if the iterator and its model are ready, %FALSE otherwise. **/ gboolean db_iterator_is_ready (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE); return IS_READY (self); } /** * db_iterator_get_mode: * @self: a #DbIterator * * Gets the mode in which the iterator is working. * * Return value: the #DbIteratorMode **/ DbIteratorMode db_iterator_get_mode (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), 0); return self->mode; } /** * db_iterator_set_mode: * @self: a #DbIterator * @mode: the #DbIteratorMode mode * * Sets the mode in which the iterator should work. **/ void db_iterator_set_mode (DbIterator * self, DbIteratorMode mode) { g_return_if_fail (DB_IS_ITERATOR (self)); self->mode = mode; if (self->model) db_iterator_set_model_mode (self); } /** * db_iterator_get_iter: * @self: a #DbIterator * @iter: (allow-none) (out): return location for selected row iter, or %NULL. * * Gets the currently selected iter. * * Return value: %TRUE if any row is selected, %FALSE otherwise. **/ gboolean db_iterator_get_iter (DbIterator * self, DbIter * iter) { g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE); if (!self->row_selected) return FALSE; *iter = self->iter; return TRUE; } /** * db_iterator_select_iter: * @self: a #DbIterator * @iter: a #DbIter * * Adds a new #DbIter to the current selection. */ void db_iterator_select_iter (DbIterator * self, DbIter * iter) { gint pos; g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (IS_READY (self)); if (!iter) return; if (!self->selected) self->selected = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, (GDestroyNotify) db_iter_free); self->iter = *iter; self->row_selected = FALSE; g_signal_emit (self, signals[ROW_NUM_CHANGED], 0); pos = db_model_get_path (self->model, iter); if (!g_hash_table_contains (self->selected, &pos)) g_hash_table_insert (self->selected, &pos, db_iter_copy (iter)); } /** * db_iterator_move_iter: * @self: a #DbIterator * @iter: a #DbIter * * Moves the iterator cursor to the specified iter, if model is ready. **/ void db_iterator_move_iter (DbIterator * self, DbIter * iter) { g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (IS_READY (self)); g_return_if_fail (self->model); if (self->row_selected && db_iter_compare (&self->iter, iter)) return; if (self->mode != DB_ITERATOR_MODE_ON_DEMAND) { if (db_model_get_row_operations (self->model, &self->iter) == DB_MODEL_ROW_OP_INSERT) db_model_reverse_operations (self->model); db_model_perform_operations (self->model, FALSE); } db_iterator_set_iter (self, iter); } /** * db_iterator_move_first: * @self: a #DbIterator * * Moves the iterator cursor to the first row. **/ void db_iterator_move_first (DbIterator * self) { DbIter iter; g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (self->model); if (db_model_get_iter_first (self->model, &iter)) db_iterator_move_iter (self, &iter); } /** * db_iterator_move_last: * @self: a #DbIterator * * Moves the iterator cursor to the last row. **/ void db_iterator_move_last (DbIterator * self) { DbIter iter; g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (self->model); if (db_model_get_last (self->model, &iter)) db_iterator_move_iter (self, &iter); } /** * db_iterator_move_previous: * @self: a #DbIterator * * Moves the iterator cursor to the previous row, or displays a message if no * exists. If no selected row, attempts to move the cursor to the first row. **/ void db_iterator_move_previous (DbIterator * self) { g_return_if_fail (DB_IS_ITERATOR (self)); if (self->row_selected) { DbIter iter = self->iter; if (db_model_iter_prev (self->model, &iter)) db_iterator_move_iter (self, &iter); else g_warning ( "Can't move the cursor to the previous " "row, because there are no more rows." ); } else db_iterator_move_first (self); } /** * db_iterator_move_next: * @self: a #DbIterator * * Moves the iterator cursor to the next row, or displays a message if no exists. * If no selected row, attempts to move the cursor to the first row. **/ void db_iterator_move_next (DbIterator * self) { g_return_if_fail (DB_IS_ITERATOR (self)); if (self->row_selected) { DbIter iter = self->iter; if (db_model_iter_next (self->model, &iter)) db_iterator_move_iter (self, &iter); else g_warning ( "Can't move the cursor to the next " "row, because there are no more rows." ); } else db_iterator_move_first (self); } /** * db_iterator_move_to: * @self: a #DbIterator * @move: a #DbIteratorMove * * Moves the iterator cursor to the predefined position. **/ void db_iterator_move_to (DbIterator * self, DbIteratorMove move) { switch (move) { case DB_ITERATOR_MOVE_FIRST: db_iterator_move_first (self); break; case DB_ITERATOR_MOVE_PREVIOUS: db_iterator_move_previous (self); break; case DB_ITERATOR_MOVE_NEXT: db_iterator_move_next (self); break; case DB_ITERATOR_MOVE_LAST: db_iterator_move_last (self); break; } } /** * db_iterator_insert: * @self: a #DbIterator * * Inserts a new row in the model and moves the iter to it, if inserted. * successfully. **/ void db_iterator_insert (DbIterator * self) { DbIter iter; g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (self->model); if (self->mode != DB_ITERATOR_MODE_ON_DEMAND) { if (db_model_get_row_operations (self->model, &self->iter) == DB_MODEL_ROW_OP_INSERT) return; db_model_perform_operations (self->model, FALSE); } if (db_model_insert (self->model, &iter)) db_iterator_set_iter (self, &iter); } /** * db_iterator_delete: * @self: a #DbIterator * * Deletes the currently selected row from the model, if any. **/ void db_iterator_delete (DbIterator * self) { g_return_if_fail (DB_IS_ITERATOR (self)); if (self->row_selected) { db_model_delete (self->model, &self->iter); if (self->mode != DB_ITERATOR_MODE_ON_DEMAND) db_model_perform_operations (self->model, FALSE); } else if (self->selected) { GList * l, * list = g_hash_table_get_values (self->selected); for (l = list; l; l = l->next) db_model_delete (self->model, l->data); if (self->mode != DB_ITERATOR_MODE_ON_DEMAND) db_model_perform_operations (self->model, FALSE); db_iterator_unselect (self); } } /** * db_iterator_refresh: * @self: a #DbIterator * * Refresh the data of the model handled by iterator. **/ void db_iterator_refresh (DbIterator * self) { g_return_if_fail (DB_IS_ITERATOR (self)); if (self->model) { db_model_refresh (self->model); db_iterator_unselect (self); } } /** * db_iterator_get_spec: * @self: a #DbIterator * @column: the column index. * * Gets the spec from the model of the specified column index. * * Return value: (transfer none) (allow-none): a #GvnParamSpec or %NULL if * can't get it because the model isn't ready. **/ const GvnParamSpec * db_iterator_get_spec (DbIterator * self, gint column) { g_return_val_if_fail (DB_IS_ITERATOR (self), NULL); if (IS_READY (self)) return db_model_get_spec (self->model, column); else return NULL; } /** * db_iterator_get_value: * @self: a #DbIterator * @column: the column index. * * Gets the value of the specified column index. * * Return value: (transfer none) (allow-none): the value or %NULL if * can't get it because the model isn't ready. **/ const GValue * db_iterator_get_value (DbIterator * self, gint column) { g_return_val_if_fail (DB_IS_ITERATOR (self), NULL); if (self->row_selected) return db_model_get_value (self->model, &self->iter, column, NULL); return NULL; } /** * db_iterator_get_column_index: * @self: a #DbIterator * @name: the name of a column of iterator. * * Retrieves the position in the query of the column called @name. * * Return value: the position of the column with name @name or -1 if there isn't * a column called name or if name is %NULL. **/ gint db_iterator_get_column_index (DbIterator * self, const gchar * name) { g_return_val_if_fail (DB_IS_ITERATOR (self), -1); g_return_val_if_fail (IS_READY (self), -1); return db_model_get_column_index (self->model, name); } /** * db_iterator_set_value: * @self: a #DbIterator * @column: the column index. * @value: a #GValue with the new value. * @err: (out) (allow-none): the return location for a #GError or %NULL. * * Sets the value of the specified column index. * * Return value: %TRUE if the value was changed, %FALSE otherwise **/ gboolean db_iterator_set_value (DbIterator * self, gint column, const GValue * value, GError ** err) { g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE); if (db_iterator_check_row_selected (self)) return db_model_set_value (self->model, &self->iter, column, value, err); return FALSE; } /** * db_iterator_add_param: * @self: a #DbIterator * @param: the param to add. * * Adds a #DbParam to the list of iterator params. **/ void db_iterator_add_param (DbIterator * self, DbParam * param) { g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (DB_IS_PARAM (param)); db_param_set_iterator (param, self); g_object_weak_ref (G_OBJECT (param), (GWeakNotify) db_iterator_unref_param, self); self->params = g_list_prepend (self->params, param); } /** * db_iterator_get_param: * @self: a #DbIterator * @column: the column name * * Creates a parameter for the specified column index and returns it. * * Return value: (transfer none): a #GvnParam **/ GvnParam * db_iterator_get_param (DbIterator * self, const gchar * column) { GList * n; GvnParam * param; g_return_val_if_fail (DB_IS_ITERATOR (self), NULL); g_return_val_if_fail (column, NULL); for (n = self->params; n; n = n->next) if (!g_strcmp0 (db_param_get_column_name (n->data), column)) break; if (!n) { param = db_param_new (column); db_iterator_add_param (self, DB_PARAM (param)); } else param = n->data; return param; } /** * db_iterator_get_params: * @self: a #DbIterator * * Gets a list of params linked with the iterator. The returned list shoud be freed. * * Return value: (element-type Db.Param) (transfer container): the #GList **/ GList * db_iterator_get_params (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), NULL); return g_list_copy (self->params); } /** * db_iterator_bind_param: * @self: a #DbIterator * @column: the column index. * @param: the column index. * * Binds the param to the specified column index. If you want to link the same * param several times you should use the db_iterator_get_param function. **/ void db_iterator_bind_param (DbIterator * self, const gchar * column, GvnParam * param) { g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (GVN_IS_PARAM (self)); gvn_param_set_master (param, db_iterator_get_param (self, column) ); } /** * db_iterator_link: * @self: a #DbIterator * @field: the field name in the iterator statement * @src: the source #DbIterator * @column: the column number of @src * * Links the iterator with another iterator parameter. **/ void db_iterator_link (DbIterator * self, const gchar * field, DbIterator * src, const gchar * column) { g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (DB_IS_ITERATOR (src)); g_return_if_fail (field); db_iterator_link_with_param (self, field, db_iterator_get_param (src, column)); } /** * db_iterator_link_with_param: * @self: a #DbIterator * @field: the field name in the iterator statement * @param: the #GvnParam * * Links the iterator with a parameter. **/ void db_iterator_link_with_param (DbIterator * self, const gchar * field, GvnParam * param) { g_return_if_fail (DB_IS_ITERATOR (self)); g_return_if_fail (GVN_IS_PARAM (param)); g_return_if_fail (self->model); g_return_if_fail (field); db_model_set_default_value_from_param (self->model, field, param, TRUE); } /** * db_iterator_get_nrows: * @self: a #DbIterator * * Gets the number of rows in the model pointed by the iterator. * * Return value: the number of rows **/ gint db_iterator_get_nrows (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), 0); if (self->model) return db_model_get_nrows (self->model); return 0; } /** * db_iterator_get_update_flags: * @self: a #DbIterator * * Gets the flags that indicate how a model can be modified. * * Return value: the flags **/ DbModelUpdateFlags db_iterator_get_update_flags (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), 0); if (self->model) return db_model_get_update_flags (self->model); return 0; } /** * db_iterator_perform_operations: * @self: a #DbIterator * * Performs all pending operations on the model. **/ void db_iterator_perform_operations (DbIterator * self) { g_return_if_fail (DB_IS_ITERATOR (self)); if (self->model) db_model_perform_operations (self->model, FALSE); } /** * db_iterator_reverse_operations: * @self: a #DbIterator * * Reverses all pending operations on the model. **/ void db_iterator_reverse_operations (DbIterator * self) { g_return_if_fail (DB_IS_ITERATOR (self)); if (self->model) db_model_reverse_operations (self->model); } /** * db_iterator_get_pending_operations: * @self: a #DbIterator * * Gets pending operations to perform in the current row. * * Return value: the pending operations **/ DbModelRowOp db_iterator_get_pending_operations (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), 0); if (self->model && (self->row_selected || self->selected)) return db_model_get_row_operations (self->model, &self->iter); return 0; } /** * db_iterator_has_pending_operations: * @self: a #DbIterator * * Checks for pending operations to perform. * * Return value: %TRUE if there are pending operations, %FALSE otherwise **/ gboolean db_iterator_has_pending_operations (DbIterator * self) { g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE); if (self->model) return db_model_has_pending_operations (self->model); return FALSE; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { PROP_MODEL = 1 ,PROP_MODE ,PROP_REMEMBER_SELECTION }; static void db_iterator_set_property (DbIterator * self, guint id, const GValue * value, GParamSpec * pspec) { switch (id) { case PROP_MODEL: db_iterator_set_model (self, g_value_get_object (value)); break; case PROP_MODE: db_iterator_set_mode (self, g_value_get_enum (value)); break; case PROP_REMEMBER_SELECTION: self->remember_selection = g_value_get_boolean (value); db_iterator_row_num_changed (self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } static void db_iterator_get_property (DbIterator * self, guint id, GValue * value, GParamSpec * pspec) { switch (id) { case PROP_MODEL: g_value_set_object (value, self->model); break; case PROP_MODE: g_value_set_enum (value, self->mode); break; case PROP_REMEMBER_SELECTION: g_value_set_boolean (value, self->remember_selection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void db_iterator_init (DbIterator * self) { self->model = NULL; self->params = NULL; self->row = 0; self->row_selected = FALSE; self->selected = NULL; } static void db_iterator_finalize (DbIterator * self) { GList * n; for (n = self->params; n; n = n->next) g_object_weak_unref (n->data, (GWeakNotify) db_iterator_unref_param, self); g_list_free (self->params); db_iterator_unselect (self); if (self->model) { g_object_disconnect (self->model ,"any_signal", db_iterator_on_model_line_inserted, self ,"any_signal", db_iterator_on_model_line_updated_after, self ,"any_signal", db_iterator_on_model_line_deleted, self ,"any_signal", db_iterator_on_model_line_deleted_after, self ,"any_signal", db_iterator_on_model_lines_reordered, self ,"any_signal", db_iterator_on_model_status_changed, self ,"any_signal", db_iterator_on_model_operations_done, self ,NULL ); g_object_unref (self->model); } G_OBJECT_CLASS (db_iterator_parent_class)->finalize (G_OBJECT (self)); } static void db_iterator_class_init (DbIteratorClass * klass) { GObjectClass * k = G_OBJECT_CLASS (klass); k->set_property = (GObjectSetPropertyFunc) db_iterator_set_property; k->get_property = (GObjectGetPropertyFunc) db_iterator_get_property; k->finalize = (GObjectFinalizeFunc) db_iterator_finalize; /** * DbIterator::iter-changed: * @iterator: the object on which the signal is emitted * * This signal is emitted when @iter moves over the @iterator model */ signals[ITER_CHANGED] = g_signal_new ("iter-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); /** * DbIterator::data-changed: * @iterator: the object on which the signal is emitted * * This signal is emitted when the model changes its data */ signals[DATA_CHANGED] = g_signal_new ("data-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); /** * DbIterator::row-num-changed: * @iterator: the object on which the signal is emitted * * This signal is emitted when the selected row changes */ signals[ROW_NUM_CHANGED] = g_signal_new ("row-num-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); /** * DbIterator::status-changed: * @iterator: the object on which the signal is emitted * @ready: #TRUE if @iterator is ready, #FALSE otherwise * * This signal is emitted when the status of the iterator changes */ signals[STATUS_CHANGED] = g_signal_new ("status-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN ); /** * DbIterator::operations-done: * @iterator: the object on which the signal is emitted * * This signal is emitted when all pending operations are performed over the * model of @iterator */ signals[OPERATIONS_DONE] = g_signal_new ("operations-done", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); g_object_class_override_property (k, PROP_MODEL, "model"); g_object_class_install_property (k, PROP_MODE, g_param_spec_enum ("mode" ,_("Mode") ,_("The mode in which the iterator is working") ,DB_TYPE_ITERATOR_MODE ,DB_ITERATOR_MODE_ON_CHANGE ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); g_object_class_install_property (k, PROP_REMEMBER_SELECTION, g_param_spec_boolean ("remember-selection" ,_("Remember selection") ,_("Wether to rememeber the selection when model is refreshed") ,TRUE ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); } static void db_iterator_model_holder_init (DbModelHolderInterface * iface) { iface->get_model = (DbModelHolderGetModelFunc) db_iterator_get_model; iface->set_model = (DbModelHolderSetModelFunc) db_iterator_set_model; } GType db_iterator_mode_get_type () { static GType type = 0; if (type == 0) { static const GEnumValue values[] = { {DB_ITERATOR_MODE_ON_CHANGE, "DB_ITERATOR_MODE_ON_CHANGE", "on-change"} ,{DB_ITERATOR_MODE_ON_ITER, "DB_ITERATOR_MODE_ON_ITER", "on-iter"} ,{DB_ITERATOR_MODE_ON_DEMAND, "DB_ITERATOR_MODE_ON_DEMAND", "on-demand"} ,{0, NULL, NULL} }; type = g_enum_register_static (g_intern_static_string ("DbIteratorMode"), values); } return type; }