If text_to_value() fails for low_val, then this code would still
destroy high_val, even though high_val hadn't been initialized,
thus accessing indeterminate data.
Ben Pfaff [Sun, 19 Aug 2012 17:30:36 +0000 (10:30 -0700)]
psppire-dialog: Add "acceptable" predicate.
PsppireDialog already has a validity predicate that allows a dialog
to easily disable "OK" and other buttons when the dialog has not
yet been completely filled. It should usually be obvious to the
user why this is the case.
The upcoming GObjectification of the missing value dialog calls for
a different kind of predicate, one where the reason is not obvious
to the user (typically because he has just made a typo or does not
understand a variable's format). In this case, the user needs more
feedback, such as a message explaining the problem.
This commit therefore introduces a second kind of predicate, the
"accept" predicate. This predicate is only checked when the user
clicks on the "OK" button.
Ben Pfaff [Thu, 9 Aug 2012 06:27:32 +0000 (23:27 -0700)]
var-type-dialog: Convert to a GObject.
The one issue I can't figure out is why this changes the look of
the dialog box so that its height is the total height of all of
the widgets in the "middlebox", rather than the maximum height
actually needed.
Ben Pfaff [Wed, 1 Aug 2012 05:55:30 +0000 (22:55 -0700)]
ods-reader: Fix ods_file_casereader_destroy() call in open function.
zreader is a "struct zip_reader *" but ods_file_casereader_destroy()
takes a "struct casereader *". However ods_file_casereader_destroy()
doesn't actually use that argument so we might as well pass NULL.
Ben Pfaff [Mon, 30 Jul 2012 06:56:09 +0000 (23:56 -0700)]
var-type-dialog: Change entries to spin buttons, add validation.
The GtkEntry boxes used for entering and displaying width and
decimal places didn't do any validation that the width and decimal
places were valid for the selected format type, so it was possible
to enter values that couldn't actually be used. This commit changes
the GtkEntry boxes into GtkSpinButton widgets that, as a side
effect, validate correct values through their attached
GtkAdjustments. This is not just safer but easier to use.
Ben Pfaff [Sat, 28 Jul 2012 21:18:40 +0000 (14:18 -0700)]
var-type-dialog: Reduce redundancy.
var_type_dialog_set_state() and on_toggle_2() had considerable
redundant code. This reduces it by adding a new function
on_active_button_change() that generalizes the two functions. I
also personally found the previous way of showing and hiding widgets
to be hard to follow; I think that the bitmap approach used here
is more straightforward.
This also consolidates the two separate signal handlers for each
button into one, and replaces the similar functions
select_treeview_from_format() and select_treeview_from_format_type()
by three functions find_format(), find_format_type(), and
select_treeview_at_index() that total less code.
Ben Pfaff [Fri, 27 Jul 2012 06:21:54 +0000 (23:21 -0700)]
var-type-dialog: Properly adjust formats when switching buttons.
The var-type-dialog based the default new format on the variable's
existing format when a button was clicked, and attempted to adjust
the width and decimals into valid range, but the adjustment wasn't
always correct, so in some cases it could pick an invalid format.
This commit uses fmt_fix_output() instead, which will always choose
a valid output format.
Ben Pfaff [Tue, 17 Jul 2012 06:36:30 +0000 (23:36 -0700)]
format: Make fmt_date_template() human-friendly, respect field width.
The strings that fmt_date_template() returned were almost but not
quite the kind of strings that humans expect to see. For one, they
always used "yy", even though the code uses 4-digit years ("yyyy")
when the field width is sufficient. Similarly, they never included
seconds (i.e. omitted ":SS"). Finally, FMT_MOYR had an "X" where
one would expect a space.
This commit corrects all of the above issues. Future commits will
make more use of fmt_date_template().
Ben Pfaff [Tue, 10 Jul 2012 04:47:02 +0000 (21:47 -0700)]
psppire-data-window: Destroy dataset from finalize.
One rule of thumb for "destroy" is that it should just unref
GObjects. This commit fixes that up for
psppire_data_window_dispose(). Previously, this could not be done
because of a reference leak in psppire_data_window_finish_init()
that caused doing the dataset destroy in finalize to crash, but
that problem was fixed in the previous commit.
Ben Pfaff [Tue, 10 Jul 2012 04:36:31 +0000 (21:36 -0700)]
psppire-data-window: Avoid reference leak to PsppireDict.
psppire_var_store_new() takes its own reference to PsppireDict so
the original reference owned by psppire_data_window_finish_init()
wasn't getting tracked anywhere.
Ben Pfaff [Sun, 8 Jul 2012 06:44:37 +0000 (23:44 -0700)]
psppire-data-window: Delete dataset when closing window.
When the user closes the window it means that he wants to close the
underlying dataset also. Otherwise the dataset essentially leaks
(in theory it's still there in the list of datasets but in practice
that takes a DATASET ACTIVATE <name> WINDOW=FRONT command to show
it).
This also fixes a Gtk-CRITICAL and following crash in the following
scenario brought up by John Darrington:
1. Start psppire
2. File | Open and load x.sav (dataset1)
3. File | New | Data (a new data window will appear: dataset2)
4. Using the window manager close the window for dataset1
5. In dataset2: File | Open and load x.sav
I'm not 100% certain of the reason that this fixes it but I think
that there's some lingering association between the dataset and the
window that this change eliminates, by eliminating the dataset along
with the window.
The code added to psppire_data_window_dispose() in this commit
should probably go in a "finalize" function instead but there seems
to be a separate problem with references to PsppireVarSheet such
that if this new code is in "finalize" then dataset_destroy() will
call dict_clear() which will invoke the callbacks for PsppireDict
which will try to access the destroyed window. On the other hand,
with this code in "dispose" the window isn't fully destroyed yet so
while the same code path gets followed it isn't fatal.
Ben Pfaff [Sat, 7 Jul 2012 20:00:19 +0000 (13:00 -0700)]
psppire-dict: Make PsppireDict not own its "struct dictionary".
I see two places where PsppireDict are created. The first is in
psppire-data-window.c. In this case, the PsppireDataWindow is
borrowing a dictionary owned by a "struct dataset" for use in its
PsppireDict. When it destroys the PsppireDict, therefore, the
dictionary must not be destroyed because the dataset still owns it.
However, this is not what actually happens, and doing the
following:
1. Start psppire
2. File | Open and load x.sav (dataset1)
3. File | New | Data (a new data window will appear: dataset2)
4. Using the window manager close the window for dataset1
5. In dataset2: File | Open and load x.sav
or similar will cause a use-after-free error.
The second use is in text-data-import-dialog.c. This code does own
the struct dictionary, but it can simply free it itself at the same
time as the PsppireDict.
There is still some underlying issue with the above scenario,
because it still reports a GtkCritical, but valgrind no longer
reports a use-after-free error.
Ben Pfaff [Mon, 9 Jul 2012 05:12:49 +0000 (22:12 -0700)]
gui: Fix Glib-GObject-WARNING when closing the active dataset.
The DATASET CLOSE command, when it acts on the active dataset, just
removes the active dataset's name, changing it to the empty string.
(This is the documented behavior.) However, the GUI relies on
every dataset having a name, so this caused the following warning:
GLib-GObject-WARNING **: value """" of type `gchararray' is invalid
or out of range for property `id' of type `gchararray'
This commit fixes the problem by giving any unnamed dataset a name
after running syntax.