|
GnuCash 2.4.99
|
00001 /* 00002 * gnc-plugin-basic-commands.c -- 00003 * 00004 * Copyright (C) 2005 David Hampton <hampton@employees.org> 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License as 00008 * published by the Free Software Foundation; either version 2 of 00009 * the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, contact: 00018 * 00019 * Free Software Foundation Voice: +1-617-542-5942 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 00021 * Boston, MA 02110-1301, USA gnu@gnu.org 00022 */ 00023 00033 #include "config.h" 00034 00035 #include <gtk/gtk.h> 00036 #include <glib/gi18n.h> 00037 #include <string.h> 00038 00039 #include "gnc-plugin-basic-commands.h" 00040 #include "gnc-ui-util.h" 00041 00042 #include "dialog-book-close.h" 00043 #include "dialog-file-access.h" 00044 #include "dialog-fincalc.h" 00045 #include "dialog-find-transactions.h" 00046 #include "dialog-sx-since-last-run.h" 00047 #include "dialog-totd.h" 00048 #include "assistant-acct-period.h" 00049 #include "assistant-loan.h" 00050 #include "gnc-engine.h" 00051 #include "gnc-file.h" 00052 #include "gnc-gui-query.h" 00053 #include "gnc-main-window.h" 00054 #include "gnc-ui.h" 00055 #include "gnc-window.h" 00056 #include "gnc-session.h" 00057 #include "gnc-plugin-page-sx-list.h" 00058 #include "gnc-plugin-file-history.h" 00059 00060 /* This static indicates the debugging module that this .o belongs to. */ 00061 static QofLogModule log_module = GNC_MOD_GUI; 00062 00063 static void gnc_plugin_basic_commands_class_init (GncPluginBasicCommandsClass *klass); 00064 static void gnc_plugin_basic_commands_init (GncPluginBasicCommands *plugin); 00065 static void gnc_plugin_basic_commands_finalize (GObject *object); 00066 00067 static void gnc_plugin_basic_commands_add_to_window (GncPlugin *plugin, GncMainWindow *window, GQuark type); 00068 static void gnc_plugin_basic_commands_main_window_page_changed(GncMainWindow *window, GncPluginPage *page, gpointer user_data); 00069 00070 /* Command callbacks */ 00071 static void gnc_main_window_cmd_file_new (GtkAction *action, GncMainWindowActionData *data); 00072 static void gnc_main_window_cmd_file_open (GtkAction *action, GncMainWindowActionData *data); 00073 static void gnc_main_window_cmd_file_save (GtkAction *action, GncMainWindowActionData *data); 00074 static void gnc_main_window_cmd_file_save_as (GtkAction *action, GncMainWindowActionData *data); 00075 static void gnc_main_window_cmd_file_revert (GtkAction *action, GncMainWindowActionData *data); 00076 static void gnc_main_window_cmd_file_export_accounts (GtkAction *action, GncMainWindowActionData *data); 00077 static void gnc_main_window_cmd_edit_tax_options (GtkAction *action, GncMainWindowActionData *data); 00078 static void gnc_main_window_cmd_actions_mortgage_loan (GtkAction *action, GncMainWindowActionData *data); 00079 static void gnc_main_window_cmd_actions_scheduled_transaction_editor (GtkAction *action, GncMainWindowActionData *data); 00080 static void gnc_main_window_cmd_actions_since_last_run (GtkAction *action, GncMainWindowActionData *data); 00081 static void gnc_main_window_cmd_actions_close_books (GtkAction *action, GncMainWindowActionData *data); 00082 static void gnc_main_window_cmd_tools_financial_calculator (GtkAction *action, GncMainWindowActionData *data); 00083 static void gnc_main_window_cmd_tools_close_book (GtkAction *action, GncMainWindowActionData *data); 00084 static void gnc_main_window_cmd_tools_find_transactions (GtkAction *action, GncMainWindowActionData *data); 00085 static void gnc_main_window_cmd_tools_price_editor (GtkAction *action, GncMainWindowActionData *data); 00086 static void gnc_main_window_cmd_tools_commodity_editor (GtkAction *action, GncMainWindowActionData *data); 00087 static void gnc_main_window_cmd_help_totd (GtkAction *action, GncMainWindowActionData *data); 00088 00089 00090 00091 #define PLUGIN_ACTIONS_NAME "gnc-plugin-basic-commands-actions" 00092 #define PLUGIN_UI_FILENAME "gnc-plugin-basic-commands-ui.xml" 00093 00096 static GtkActionEntry gnc_plugin_actions [] = 00097 { 00098 00099 /* File menu */ 00100 00101 { 00102 "FileNewAction", GTK_STOCK_NEW, N_("New _File"), "<control>n", 00103 N_("Create a new file"), 00104 G_CALLBACK (gnc_main_window_cmd_file_new) 00105 }, 00106 { 00107 "FileOpenAction", GTK_STOCK_OPEN, N_("_Open..."), "<control>o", 00108 N_("Open an existing GnuCash file"), 00109 G_CALLBACK (gnc_main_window_cmd_file_open) 00110 }, 00111 { 00112 "FileSaveAction", GTK_STOCK_SAVE, N_("_Save"), "<control>s", 00113 N_("Save the current file"), 00114 G_CALLBACK (gnc_main_window_cmd_file_save) 00115 }, 00116 { 00117 "FileSaveAsAction", GTK_STOCK_SAVE_AS, N_("Save _As..."), "<shift><control>s", 00118 N_("Save this file with a different name"), 00119 G_CALLBACK (gnc_main_window_cmd_file_save_as) 00120 }, 00121 { 00122 "FileRevertAction", GTK_STOCK_REVERT_TO_SAVED, N_("Re_vert"), NULL, 00123 N_("Reload the current database, reverting all unsaved changes"), 00124 G_CALLBACK (gnc_main_window_cmd_file_revert) 00125 }, 00126 { 00127 "FileExportAccountsAction", GTK_STOCK_CONVERT, 00128 N_("Export _Accounts"), NULL, 00129 N_("Export the account hierarchy to a new GnuCash datafile"), 00130 G_CALLBACK (gnc_main_window_cmd_file_export_accounts) 00131 }, 00132 00133 /* Edit menu */ 00134 00135 { 00136 "EditFindTransactionsAction", GTK_STOCK_FIND, N_("_Find..."), "<control>f", 00137 N_("Find transactions with a search"), 00138 G_CALLBACK (gnc_main_window_cmd_tools_find_transactions) 00139 }, 00140 { 00141 "EditTaxOptionsAction", NULL, 00142 N_("Ta_x Report Options"), NULL, 00143 /* Translators: currently implemented are * 00144 * US: income tax and * 00145 * DE: VAT * 00146 * So adjust this string */ 00147 N_("Setup relevant accounts for tax reports, e.g. US income tax"), 00148 G_CALLBACK (gnc_main_window_cmd_edit_tax_options) 00149 }, 00150 00151 /* Actions menu */ 00152 00153 { "ActionsScheduledTransactionsAction", NULL, N_("_Scheduled Transactions"), NULL, NULL, NULL }, 00154 { 00155 "ActionsScheduledTransactionEditorAction", NULL, N_("_Scheduled Transaction Editor"), NULL, 00156 N_("The list of Scheduled Transactions"), 00157 G_CALLBACK (gnc_main_window_cmd_actions_scheduled_transaction_editor) 00158 }, 00159 { 00160 "ActionsSinceLastRunAction", NULL, N_("Since _Last Run..."), NULL, 00161 N_("Create Scheduled Transactions since the last time run"), 00162 G_CALLBACK (gnc_main_window_cmd_actions_since_last_run) 00163 }, 00164 { 00165 "ActionsMortgageLoanAction", NULL, N_("_Mortgage & Loan Repayment..."), NULL, 00166 N_("Setup scheduled transactions for repayment of a loan"), 00167 G_CALLBACK (gnc_main_window_cmd_actions_mortgage_loan) 00168 }, 00169 { "ActionsBudgetAction", NULL, N_("B_udget"), NULL, NULL, NULL }, 00170 #ifdef CLOSE_BOOKS_ACTUALLY_WORKS 00171 { 00172 "ActionsCloseBooksAction", NULL, N_("Close _Books"), NULL, 00173 N_("Archive old data using accounting periods"), 00174 G_CALLBACK (gnc_main_window_cmd_actions_close_books) 00175 }, 00176 #endif // CLOSE_BOOKS_ACTUALLY_WORKS 00177 00178 /* Tools menu */ 00179 00180 { 00181 "ToolsPriceEditorAction", NULL, N_("_Price Editor"), NULL, 00182 N_("View and edit the prices for stocks and mutual funds"), 00183 G_CALLBACK (gnc_main_window_cmd_tools_price_editor) 00184 }, 00185 { 00186 "ToolsCommodityEditorAction", NULL, N_("_Security Editor"), NULL, 00187 N_("View and edit the commodities for stocks and mutual funds"), 00188 G_CALLBACK (gnc_main_window_cmd_tools_commodity_editor) 00189 }, 00190 { 00191 "ToolsFinancialCalculatorAction", NULL, N_("_Loan Repayment Calculator"), NULL, 00192 N_("Use the loan/mortgage repayment calculator"), 00193 G_CALLBACK (gnc_main_window_cmd_tools_financial_calculator) 00194 }, 00195 { 00196 "ToolsBookCloseAction", NULL, N_("_Close Book"), NULL, 00197 N_("Close the Book at the end of the Period"), 00198 G_CALLBACK (gnc_main_window_cmd_tools_close_book) 00199 }, 00200 00201 /* Help menu */ 00202 00203 { 00204 "HelpTipsOfTheDayAction", NULL, N_("_Tips Of The Day"), NULL, 00205 N_("View the Tips of the Day"), 00206 G_CALLBACK (gnc_main_window_cmd_help_totd) 00207 }, 00208 }; 00210 static guint gnc_plugin_n_actions = G_N_ELEMENTS (gnc_plugin_actions); 00211 00212 00216 static const gchar *gnc_plugin_important_actions[] = 00217 { 00218 "FileSaveAction", 00219 NULL, 00220 }; 00221 00226 static const gchar *readonly_inactive_actions[] = 00227 { 00228 "ToolsBookCloseAction", 00229 NULL 00230 }; 00231 00234 typedef struct GncPluginBasicCommandsPrivate 00235 { 00236 gpointer dummy; 00237 } GncPluginBasicCommandsPrivate; 00238 00239 #define GNC_PLUGIN_BASIC_COMMANDS_GET_PRIVATE(o) \ 00240 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_BASIC_COMMANDS, GncPluginBasicCommandsPrivate)) 00241 00243 static GObjectClass *parent_class = NULL; 00244 00245 00246 /* Get the type of the basic commands menu plugin. */ 00247 GType 00248 gnc_plugin_basic_commands_get_type (void) 00249 { 00250 static GType gnc_plugin_basic_commands_type = 0; 00251 00252 if (gnc_plugin_basic_commands_type == 0) 00253 { 00254 static const GTypeInfo our_info = 00255 { 00256 sizeof (GncPluginBasicCommandsClass), 00257 NULL, /* base_init */ 00258 NULL, /* base_finalize */ 00259 (GClassInitFunc) gnc_plugin_basic_commands_class_init, 00260 NULL, /* class_finalize */ 00261 NULL, /* class_data */ 00262 sizeof (GncPluginBasicCommands), 00263 0, /* n_preallocs */ 00264 (GInstanceInitFunc) gnc_plugin_basic_commands_init 00265 }; 00266 00267 gnc_plugin_basic_commands_type = g_type_register_static (GNC_TYPE_PLUGIN, 00268 "GncPluginBasicCommands", 00269 &our_info, 0); 00270 } 00271 00272 return gnc_plugin_basic_commands_type; 00273 } 00274 00275 00277 GncPlugin * 00278 gnc_plugin_basic_commands_new (void) 00279 { 00280 GncPluginBasicCommands *plugin; 00281 00282 /* We just need to mention it, so the GType is registered and will be 00283 * reflected during plugin-page restore. */ 00284 GNC_TYPE_PLUGIN_PAGE_SX_LIST; 00285 00286 plugin = g_object_new (GNC_TYPE_PLUGIN_BASIC_COMMANDS, NULL); 00287 00288 return GNC_PLUGIN (plugin); 00289 } 00290 00305 static void 00306 gnc_plugin_basic_commands_add_to_window (GncPlugin *plugin, 00307 GncMainWindow *window, 00308 GQuark type) 00309 { 00310 g_signal_connect(window, "page_changed", 00311 G_CALLBACK(gnc_plugin_basic_commands_main_window_page_changed), 00312 plugin); 00313 } 00314 00317 static void update_inactive_actions(GncPluginPage *plugin_page) 00318 { 00319 GncMainWindow *window; 00320 GtkActionGroup *action_group; 00321 GtkAction *file_save_action; 00322 00323 // We are readonly - so we have to switch particular actions to inactive. 00324 gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book()); 00325 gboolean is_dirty = qof_book_session_not_saved (gnc_get_current_book ()); 00326 00327 // We continue only if the current page is a plugin page 00328 if (!plugin_page || !GNC_IS_PLUGIN_PAGE(plugin_page)) 00329 return; 00330 00331 window = GNC_MAIN_WINDOW(plugin_page->window); 00332 g_return_if_fail(GNC_IS_MAIN_WINDOW(window)); 00333 action_group = gnc_main_window_get_action_group(window, PLUGIN_ACTIONS_NAME); 00334 g_return_if_fail(GTK_IS_ACTION_GROUP(action_group)); 00335 00336 /* Set the action's sensitivity */ 00337 gnc_plugin_update_actions (action_group, readonly_inactive_actions, 00338 "sensitive", is_readwrite); 00339 /* FileSaveAction needs to be set separately because it has *two* conditions */ 00340 file_save_action = gtk_action_group_get_action (action_group, 00341 "FileSaveAction"); 00342 gtk_action_set_sensitive (file_save_action, is_readwrite && is_dirty); 00343 } 00344 00345 static void 00346 gnc_plugin_basic_commands_main_window_page_changed(GncMainWindow *window, 00347 GncPluginPage *page, 00348 gpointer user_data) 00349 { 00350 /* Make sure not to call this with a NULL GncPluginPage */ 00351 if (page) 00352 { 00353 // Update the action sensitivity due to read-only 00354 update_inactive_actions(page); 00355 } 00356 } 00357 00365 static void 00366 gnc_plugin_basic_commands_class_init (GncPluginBasicCommandsClass *klass) 00367 { 00368 GObjectClass *object_class = G_OBJECT_CLASS (klass); 00369 GncPluginClass *plugin_class = GNC_PLUGIN_CLASS (klass); 00370 00371 parent_class = g_type_class_peek_parent (klass); 00372 00373 object_class->finalize = gnc_plugin_basic_commands_finalize; 00374 00375 /* plugin info */ 00376 plugin_class->plugin_name = GNC_PLUGIN_BASIC_COMMANDS_NAME; 00377 00378 /* function overrides */ 00379 plugin_class->add_to_window = gnc_plugin_basic_commands_add_to_window; 00380 00381 /* widget addition/removal */ 00382 plugin_class->actions_name = PLUGIN_ACTIONS_NAME; 00383 plugin_class->actions = gnc_plugin_actions; 00384 plugin_class->n_actions = gnc_plugin_n_actions; 00385 plugin_class->important_actions = gnc_plugin_important_actions; 00386 plugin_class->ui_filename = PLUGIN_UI_FILENAME; 00387 00388 g_type_class_add_private(klass, sizeof(GncPluginBasicCommandsPrivate)); 00389 } 00390 00391 00397 static void 00398 gnc_plugin_basic_commands_init (GncPluginBasicCommands *plugin) 00399 { 00400 } 00401 00402 00411 static void 00412 gnc_plugin_basic_commands_finalize (GObject *object) 00413 { 00414 GncPluginBasicCommands *plugin; 00415 GncPluginBasicCommandsPrivate *priv; 00416 00417 g_return_if_fail (GNC_IS_PLUGIN_BASIC_COMMANDS (object)); 00418 00419 plugin = GNC_PLUGIN_BASIC_COMMANDS (object); 00420 priv = GNC_PLUGIN_BASIC_COMMANDS_GET_PRIVATE (plugin); 00421 00422 G_OBJECT_CLASS (parent_class)->finalize (object); 00423 } 00424 00425 /************************************************************ 00426 * Command Callbacks * 00427 ************************************************************/ 00428 00429 static void 00430 gnc_main_window_cmd_file_new (GtkAction *action, GncMainWindowActionData *data) 00431 { 00432 if (!gnc_main_window_all_finish_pending()) 00433 return; 00434 00435 gnc_file_new (); 00436 /* FIXME GNOME 2 Port (update the title etc.) */ 00437 } 00438 00439 static void 00440 gnc_main_window_cmd_file_open (GtkAction *action, GncMainWindowActionData *data) 00441 { 00442 g_return_if_fail (data != NULL); 00443 00444 if (!gnc_main_window_all_finish_pending()) 00445 return; 00446 00447 gnc_window_set_progressbar_window (GNC_WINDOW(data->window)); 00448 #ifdef HAVE_DBI_DBI_H 00449 gnc_ui_file_access_for_open(); 00450 #else 00451 gnc_file_open (); 00452 #endif 00453 gnc_window_set_progressbar_window (NULL); 00454 } 00455 00456 static void 00457 gnc_main_window_cmd_file_save (GtkAction *action, GncMainWindowActionData *data) 00458 { 00459 g_return_if_fail (data != NULL); 00460 00461 if (!gnc_main_window_all_finish_pending()) 00462 return; 00463 00464 gnc_window_set_progressbar_window (GNC_WINDOW(data->window)); 00465 gnc_file_save (); 00466 gnc_window_set_progressbar_window (NULL); 00467 /* FIXME GNOME 2 Port (update the title etc.) */ 00468 } 00469 00470 static void 00471 gnc_main_window_cmd_file_save_as (GtkAction *action, GncMainWindowActionData *data) 00472 { 00473 g_return_if_fail (data != NULL); 00474 00475 if (!gnc_main_window_all_finish_pending()) 00476 return; 00477 00478 gnc_window_set_progressbar_window (GNC_WINDOW(data->window)); 00479 #ifdef HAVE_DBI_DBI_H 00480 gnc_ui_file_access_for_save_as(); 00481 #else 00482 gnc_file_save_as (); 00483 #endif 00484 gnc_window_set_progressbar_window (NULL); 00485 /* FIXME GNOME 2 Port (update the title etc.) */ 00486 } 00487 00488 static void 00489 gnc_main_window_cmd_file_revert (GtkAction *action, GncMainWindowActionData *data) 00490 { 00491 g_return_if_fail (data != NULL); 00492 00493 if (!gnc_main_window_all_finish_pending()) 00494 return; 00495 00496 gnc_window_set_progressbar_window (GNC_WINDOW(data->window)); 00497 00498 { 00499 gchar *filename = gnc_history_get_last(); 00500 // And actually open the current file again 00501 gnc_file_open_file (filename, qof_book_is_readonly(gnc_get_current_book())); 00502 g_free(filename); 00503 } 00504 00505 gnc_window_set_progressbar_window (NULL); 00506 } 00507 00508 static void 00509 gnc_main_window_cmd_file_export_accounts (GtkAction *action, GncMainWindowActionData *data) 00510 { 00511 g_return_if_fail (data != NULL); 00512 00513 gnc_window_set_progressbar_window (GNC_WINDOW(data->window)); 00514 #ifdef HAVE_DBI_DBI_H 00515 gnc_ui_file_access_for_export(); 00516 #else 00517 gnc_file_export (); 00518 #endif 00519 gnc_window_set_progressbar_window (NULL); 00520 /* FIXME GNOME 2 Port (update the title etc.) */ 00521 /* gnc_refresh_main_window_info (); */ 00522 } 00523 00524 static void 00525 gnc_main_window_cmd_edit_tax_options (GtkAction *action, GncMainWindowActionData *data) 00526 { 00527 g_return_if_fail (data != NULL); 00528 00529 gnc_tax_info_dialog (GTK_WIDGET (data->window)); 00530 } 00531 00532 static void 00533 gnc_main_window_cmd_actions_scheduled_transaction_editor (GtkAction *action, GncMainWindowActionData *data) 00534 { 00535 GncPluginPage *page = gnc_plugin_page_sx_list_new(); 00536 gnc_main_window_open_page(NULL, page); 00537 } 00538 00539 static void 00540 gnc_main_window_cmd_actions_since_last_run (GtkAction *action, GncMainWindowActionData *data) 00541 { 00542 GncMainWindow *window; 00543 GncSxInstanceModel *sx_instances; 00544 GncSxSummary summary; 00545 GList *auto_created_txns = NULL; 00546 const char *nothing_to_do_msg = 00547 _( "There are no Scheduled Transactions to be entered at this time." ); 00548 00549 g_return_if_fail (data != NULL); 00550 00551 window = data->window; 00552 00553 sx_instances = gnc_sx_get_current_instances(); 00554 gnc_sx_instance_model_summarize(sx_instances, &summary); 00555 gnc_sx_instance_model_effect_change(sx_instances, TRUE, &auto_created_txns, NULL); 00556 if (summary.need_dialog) 00557 { 00558 gnc_ui_sx_since_last_run_dialog(sx_instances, auto_created_txns); 00559 auto_created_txns = NULL; 00560 } 00561 else 00562 { 00563 if (summary.num_auto_create_no_notify_instances == 0) 00564 { 00565 gnc_info_dialog(GTK_WIDGET(&window->gtk_window), "%s", nothing_to_do_msg); 00566 } 00567 else 00568 { 00569 gnc_info_dialog(GTK_WIDGET(&window->gtk_window), ngettext 00570 /* Translators: %d is the number of transactions. This is a 00571 ngettext(3) message. */ 00572 ("There are no Scheduled Transactions to be entered at this time. " 00573 "(%d transaction automatically created)", 00574 "There are no Scheduled Transactions to be entered at this time. " 00575 "(%d transactions automatically created)", 00576 summary.num_auto_create_no_notify_instances), 00577 summary.num_auto_create_no_notify_instances); 00578 } 00579 } 00580 g_list_free(auto_created_txns); 00581 g_object_unref(G_OBJECT(sx_instances)); 00582 } 00583 00584 static void 00585 gnc_main_window_cmd_actions_mortgage_loan (GtkAction *action, GncMainWindowActionData *data) 00586 { 00587 gnc_ui_sx_loan_assistant_create (); 00588 } 00589 00590 static void 00591 gnc_main_window_cmd_actions_close_books (GtkAction *action, GncMainWindowActionData *data) 00592 { 00593 gnc_acct_period_dialog(); 00594 } 00595 00596 static void 00597 gnc_main_window_cmd_tools_price_editor (GtkAction *action, GncMainWindowActionData *data) 00598 { 00599 gnc_set_busy_cursor(NULL, TRUE); 00600 gnc_prices_dialog (NULL); 00601 gnc_unset_busy_cursor(NULL); 00602 } 00603 00604 static void 00605 gnc_main_window_cmd_tools_commodity_editor (GtkAction *action, GncMainWindowActionData *data) 00606 { 00607 gnc_set_busy_cursor(NULL, TRUE); 00608 gnc_commodities_dialog (NULL); 00609 gnc_unset_busy_cursor(NULL); 00610 } 00611 00612 static void 00613 gnc_main_window_cmd_tools_financial_calculator (GtkAction *action, GncMainWindowActionData *data) 00614 { 00615 gnc_ui_fincalc_dialog_create(); 00616 } 00617 00618 static void 00619 gnc_main_window_cmd_tools_close_book (GtkAction *action, GncMainWindowActionData *data) 00620 { 00621 gnc_ui_close_book(gnc_get_current_book()); 00622 } 00623 00624 static void 00625 gnc_main_window_cmd_tools_find_transactions (GtkAction *action, GncMainWindowActionData *data) 00626 { 00627 gnc_ui_find_transactions_dialog_create (NULL); 00628 } 00629 00630 static void 00631 gnc_main_window_cmd_help_totd (GtkAction *action, GncMainWindowActionData *data) 00632 { 00633 g_return_if_fail (data != NULL); 00634 00635 gnc_totd_dialog(GTK_WINDOW(data->window), FALSE); 00636 } 00637
1.7.4