-
-
-
This video shows Treebard's opening dialog, statusbar and statusbar tooltips, menu buttons, events table, image gallery, family table and more.
-
-
-
This video shows how to change the current person with an ID number or name, and how to select the right person if there are several people by the same name. How to change the main picture for the current person. Some details of the family table. A peek at the person search feature.
-
-
-
This video covers creating and deleting non-couple events. Making a new person. Previewing, applying, creating and deleting color schemes. Finding a person's ID number.
-
-
-
families table, editing conclusions in events table, open roles dialog, change date formats, date input, name policy
-
-
-
In this video we'll be looking on as Treebard's family table functionalities are tested one at a time. The code for this feature has been some months in the making and much of it is ready for prime time, but those sub-features which don't work perfectly yet have to be pin-pointed after a recent rewrite.
-
-
-
After working on Treebard's families table for almost six months, it's finally ready to use with all features tested. There will be bugs to work out and improvements to make but this is the real deal, the families table is now a functional part of Treebard's front page, the current person tab.
-
-
-
Treebard's places functionalities have been around for a long time, and they used to work well. Recently I noticed that since so much water has gone under the bridge lately, some of the places functionalities got carried off downstream somewhere, and instead of wasting a lot of time trying to figure out what went wrong, I went ahead and redesigned the whole entire places feature almost from scratch. Massive improvements were made to the database structure as related to places, the autofill functionality was improved, the problem of column width flashing back and forth during autofill was fixed in the conclusions table, and the duplicate places dialog was completely redesigned.
-
-
-
The conclusions table cells are no longer inputs but you can overlay an input on the cell to edit the cell. This allows the use of multi-line labels for the cells, resulting in a sleeker table with nice narrow columns. All this is in support of Treebard's inflexible policy of never using resizable columns, so that the entire content of any table can always be read without any finagling. Making a small correction in dates.py module to accomodate the new overlay edit inputs. Demonstration of Treebard's super flexible date input feature. Invitation to fork Treebard at the Github repo (see link below) and improve it in any way you want. Demonstration of the new gallery dialogs for persons, places, and sources. A peek at the new Names tab functionality for adding a name to an existing person. User settings for fonts. Opening a different tree with the Recent Tree menu item. Making a small correction to a database by adding a column to a table. Assertions, sources, and conclusions. The assertions tab. @26:52 "These would be unlinked conclusions..." should be "...unlinked assertions..." i.e. assertions that are saved in the database but are not linked to any conclusion. The repositories dialog. New examples shown at top of widgets.py for making dynamic widgets that respond to mouse events etc. and still recolorize properly when the user changes the color scheme. Demonstration of the new conclusions table cell edit functionality. The new place dialog. Making a small correction to places.py. Using the new event type feature in the Types tab. the Dates tab in the Preferences tab.
-
-
-
The do list tab. The preferences tab. The types tab. Setting the default image directory for the tree. Adding images to the tree. Linking added images to the current person, place or source. Sending an image to the graphics tab for editing. Resizing an image. Linking an image to the current source. Unlink an image from the current element. Unlink an image from all elements. Choose to not see any default images. Using your own default images for the big buttons that open the image galleries instead of Treebard's built-in default images. Reverting to Treebard's built-in default images.
-
-
-
Cropping an image. Adding text and border to an image. Adding a border without text to the image. Trying to add a caption to the image in the database, to display along with the image in the images gallery. Adding a new person by clicking the plus sign icon in the menu. (It's not broken, just don't type a plus sign after the name in the add person dialog.) Adding a new person by typing their name in the current person area. Selecting multiple images to be linked to the new person, while also resizing each one independently at the same time. Adding a person with the same name as a person who is already in the tree.
-
-
-
-
-
In Treebard genealogy database software, the events table is big, front-and-center on the top tab which is the current person tab. Based on existing birth events stored in the database, Treebard auto-creates an offspring event to show in the parents' events tables. A hitch in this git-along was discovered and fixed, giving our home audience a chance to gawk at the innards of Treebard's Python code as well as some details of the recently improved SQLite database structure.
In this series of videos, a slightly deeper technical stance will be taken in order to try and show that ordinary yokels like myself can write their own genieware apps.
Treebard GPS is a showcase of functionalities, a work in progress that's intended to demonstrate user interface features and data structures that are considerably better than what's generally available in existing genealogy apps.
-
-
-
-
-
Professor U. d'Guru tries to make places in Gramps, especially nested places, especially nested places with more than one enclosing place. In the spirit of fairness, here's a video that shows how this is actually done: https://www.youtube.com/watch?v=z_Svav0tV1w
In this series of videos a newcomer to Gramps will be opening it up and trying to do something without any planning or studying. Then he will give his first impression of how easy or hard it is to figure out how to use the program, and how it might be improved. There will be some comparison to Treebard GPS, which is a work in progress being attempted by a team of one who is a hobby-level coder also working in Python.
-
-
-
Professor U. d'Guru tries to figure out how to use dark mode in Gramps, without plug-ins or add-ons. How to change the color of boxes including the color of the font in the box, so that the text is visible.
-
-
-
Professor U. d'Guru tries to figure out how to get repositories, sources and citations into a Gramps database, and how to link citations to events. Special attention is given to whether or not a given citation is saved with a unique ID so it can be used over and over, eliminating the need to copy/paste a citation multiple times. A tutorial for this process exists here: https://www.youtube.com/watch?v=oY6nn3Eobb4
-
-
-
Professor U. d'Guru tries to figure out how to find and install a dark mode plug-in for Gramps, without a simple set of instructions which apparently doesn't exist, since apparently only true computer geeks are supposed to attempt this.
Treebard GPS, in constrast, comes with a simple and flexible themes system that is self-contained. This was one of the first parts of Treebard that was created when the founder of Treebard knew almost nothing about Python and Tkinter, back in 2018. Treebard's themes feature is in approximately its fourth incarnation right now.
The attempt to get a dark mode for Gramps was determined possible, but the secret instructions for how to make it simply happen have still deluded us. Possibly the instructions are here: https://gramps-project.org/wiki/index.php/Addon:Themes
-
-
-
-
-
This video introduces the purpose of Treebard GPS, a one-man labor of love intended to demonstrate desirable features of genealogy software. Specifically, this video focuses on the attitudes of Treebard's creator Uncle Buddy a.k.a. Professor U. d'Guru who admits that he is guilty of not trying to be something that he is not, while encouraging ordinary individuals to do what he's apparently able to do: to create their own genealogy software.
Treebard is completely free (unfinished) software that can be borrowed, used or stolen without permission and used for anything you want. Treebard is not a complete genealogy program, but is meant to serve as a showcase of functionalities for genealogy's most primary features.
The data storage structure is intended to be good enough to replace GEDCOM as a standard for file sharing. The user interface is intended to demonstrate how complex stored data can be accessed and manipulated in a friendly, intuitive, simple way that anyone can learn.
-
-
-
This video emphasizes the purpose of Treebard GPS, a one-man labor of love intended to demonstrate desirable features of genealogy software. Specifically, this video focuses on the attitudes of Treebard's creator Uncle Buddy a.k.a. Professor U. d'Guru who admits that he is guilty of not trying to be something that he is not, while encouraging ordinary individuals to do what he's apparently able to do: to create their own genealogy software.
-
-
-
If you've ever thought that writing your own genealogy software was the only way it's ever gonna get done right, well you ain't alone, I've been on that slow track for 4-1/2 years. If I can do it, you can do it better. This is Professor U. d'Guru coming at ya from Treebard University, together we can save the world with genealogy, so let's get it done, why don't we.
Actually I tend to work alone, but it's a nice sentiment--teamwork that is--though it's not something I ever had much of a feel for. But be that as it may, Treebard is there for everyone to use to their heart's content, especially those special someones who would love to personally replace the existing commercial genealogy software with some universally accessible software that actually works.
-
-
-
-
-
Explore the GEDCOM text file, which is human-readable and easy to understand. Identify what you do and don't understand about the text in the GEDCOM file. This is gonna be fun and easy. Parsing GEDCOM lines with Python is the easy part. The more challenging part will be matching my database structure to the way GEDCOM is structured.
The purpose of this new video series is to demonstrate in live action an ordinary genealogist/hobbyist learning from scratch how to write Python code for his fledgling genealogy app, which will allow data to be imported and exported to and from other genieware apps.
-
-
-
Answers to questions raised in the last video. Some other Python parsers for GEDCOM. A brainstorm about how to replace GEDCOM and what it should be replaced by. Review of my first code written to parse a GEDCOM file.
-
-
-
The difference between identifiers and pointers. Rant: GEDCOM itself is easier to read and understand than the documentation that explains it. Some Python code that creates a list of unique tags used in the GEDCOM file being parsed. Looking up tags to see what they're for. Discussion: events, attributes, conclusions and assertions.
-
-
-
Some websites for researching GEDCOM, including a guide on how to handle importing custom tags. Some samples of non-GEDCOM data handled and not handled by the importing apps. Import exception reports of Gramps and Family Historian after importing to each of these apps an identical GEDCOM file created by Genbox. Musings on the right way to start writing the Python GEDCOM parser.
-
-
-
Two Python classes written to import GEDCOM files into a default Treebard database. Demonstration of the import process and the results. Discussion of some of Treebard policies or attitudes about how to store data or what sort of things should and should not be imported, i.e. what to do with user-defined or custom GEDCOM tags? Is a standard that allows non-standard usage really a standard?
-
-
-
Code written to add GEDCOM pointers to database as person ID foreign keys. Redundancy in GEDCOM family pointers. Demonstration of importing GEDCOM to Treebard and review of the results. Looking at how foreign keys are used in SQL tables. Next step: more level 1 GEDCOM tags.
-
-
-
Two approaches to organizing the GEDCOM reading. Details of the Python code for reading line levels 1 and 2. Why some data has to be saved in collections and input after the file is read. Running the code. The resulting families dictionary and what is redundant about the way GEDCOM expects developers to export family members and their relationships.
-
-
-
A simple way, while parsing lines, to save and find the previously accessed data as it is needed in subsequent lines. The code flow and the results in the database. A new direction: import conventional GEDCOM into a new kind of data-sharing text-file utility which is similar to GEDCOM in the good ways but not in the bad ways. Made to match SQL and real world data relationships. The code and results so far.
-
-
-
A look at some subordinate lines in GEDCOM that should be zero lines. A peek at SQL queries and how they are kept out of the code to make the code easier to read. How much work has to be done to get data from GEDCOM translated into a form compatible with realistically complex data structures. Is GEDCOM even worth the trouble?
-
-
-
-
-
In this series of videos, I'll select a real family tree to try and create from scratch, while at the same time demonstrating or summarizing the process of building a new Treebard feature from the bottom up. The feature I'll be adding is the Assertions & Sources Dialog that opens when you click a SOURCES button in a row of the conclusions table on the current person tab. Also pictured in this video is my forum or blog.
The new family tree that will be started is for inventor Charles D. Gregory, who is a mystery man that can't be found. But the man who appears to possibly be him had a lifelong habit of maintaining two separate identities. I'd like to prove that "Charles D. Gregory" was another of this man's aliases. So before work on the assertions dialog can start, we will create a new feature in Treebard's names tab wherein a person that already exists in the database can get a new name or his existing name can be changed. Videos 002 thru 010 in this series are about this naming feature, so if you want to skip that part, watch this intro video and then go directly to 011 where work will begin on the assertions and sources dialog.
Treebard GPS is a showcase of functionalities, a work in progress that's intended to demonstrate user interface features and data structures that are considerably better than what's generally available in existing genealogy apps.
-
-
-
In the last video I showed how to change a person's name manually in the SQLite console. This time I show the process of figuring out where and how to put a Tkinter widget in the interface so that next time I want to change a name, I can do it with the Treebard interface instead of manually opening up the database in the SQLite console. In the next several videos (thru 010), more widgets will be added to the names tab so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be. There will also be a field for adding a new name, and an OK button.
Specifically in this video it's decided which part of which module to write the code in, and how to reference the new widget's parent (the widget that will be its container, for example). Some sample widgets are created.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video, Professor U. d'Guru, a Python/Tkinter/SQLite hobbyist, demonstrates getting data from two different database tables using a simple SQL join. Designing the intended feature based on what kind of data needs to be displayed and what's going to be done with the data. Gridding Tkinter widgets in columns and rows. Python format strings to mix hard-coded and dynamically varying text in a label. Tkinter widgets are Python classes. Simple ways in which the Notepad++ code editor is better than Atom or Visual Studio Code. Treebard widgets are inherited as sub-classes of Tkinter widgets as part of Treebard's system for changing the app's color scheme instantly without resorting to ttk widgets or ttk.Style. The root is a commonly-used name for an instance of the tkinter.Tk class. SQLite database connection, query result tables `fetchall()`.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video: Tkinter's columnspan option. Treebard's unique & capable instant color-scheme changer and Toykinter widgets. Adding padding to Tkinter widgets. Unofficial Tkinter documentation by John Shipman (it is available free online). Tkinter is extremely stable and reliable, and comes with Python; it is not obsolete, but is well loved by many Python developers. Looking at what options to use with a Tkinter widget such as Checkbutton. A set of Radiobuttons uses one variable, but each Checkbutton uses its own variable. Creating Tkinter widgets and variables in a `for` loop. Saving Tkinter variables in a list or dictionary.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video: Using Python's join() method to get rid of unwanted curly braces in the Tkinter display. Tkinter's `sticky` and `anchor` options in formatting a grid of widgets. The Checkbutton's `variable` option. Python's `self` and instance variables for expanding a variable's domain. The interaction of Tkinter's `anchor` and `sticky` options in formatting layout of widget position.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video: passing the SQLite connection and cursor (e.g. `conn` and `cur`) to avoid repetitive connections to the database. Deciding what kind of Python collection to store references in. Getting a value from a Toykinter Combobox. Python class instance name replaces `self`. Keep SQL queries readable by writing two simple queries instead of one complex query. SQLite `cur.fetchone()` for a single query result. Python includes Tkinter and SQLite and is very easy to install. Remember to call `conn.commit()` when doing `delete`, `insert`, or `update` queries in SQLite.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video: Editing multiple names at the click of one button. Deleting text from an input once it's not needed anymore. Making a new record in the database table with an `insert` query. Changing a variable in every module where it exists with one button, using Notepad++.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video: Tkinter's `get()` method. Python `for` and `if` expressions define separate domains for their variables. Figuring out what conditions to test for, and creating a guard clause for conditions that should never exist, in order to cut down on indented code. Using Python's `return` to stop a function from running all the way. Solve problems by simplifying. Simplify genieware by designing on the current person basis. Using some hard-coded (fake) data temporarily so a necessary step can be put off till later.
-
-
-
The next few videos in this series (thru 010) will be about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
Specifically in this video: Construct widgets in the desired tab traversal order. Defining variables after they're used will cause an error. Don't do something in a loop for no reason. Changing the duration of Treebard's splash screen display. Adding more widgets to each row, and making room to do it. Why I don't have a shiny image. Make padding/gaps/spaces "proportional" to each other (I said "symmetrical" in the video.) GUI events triggered on focusing out of a widget can be tricky; buttons are easier. Nested functions are OK but they make a long function even longer. Don't try to memorize everything. Changing string order by using Python's `split()` method to turn the string into a list, then re-ordering the list. Using Python's `pop()` and `insert.()` list methods. How the name sort order will be used later. Using Python's `join()` method to turn a list into a string.
-
-
-
This is the last video in the sub-topic about adding the new-name and edit-name features to the names tab. More widgets are added so the user can decide which of a person's names he wants to change, what to change it to, and what name type it will be.
The next video will start the process of populating the assertions & sources dialog with widgets, data, and functionalities.
Specifically in this video: Parameterizing a function so it can be re-used. Using a lambda custom function so extra arguments can be added to a Tkinter button command. If the developer finds his feature hard to use, the user will find it harder. Add items to the do list as soon as you think of them. Writing a procedure to adjust tab order. Tkinter's built-in `widget.winfo_children()` and `widget.lift()` methods. Doing a SQLite `DELETE` query without ruining your life.
-
-
-
This is the first video in the series which begins the actual process of trying to pin down the details of how to create an assertions, citations, and sources dialog.
Specifically in this video: a look at the bare skeleton of the AssertionsDialog class. We need genealogy software that wasn't created in a hurry. Introduction to the mystery subject of the family tree we'll be trying to make as a test of the functionality we're trying to build. Citations are an element of genealogy, they need a primary key. General description of the goal. Statusbar tooltips and right-click context help. Description of some Toykinter widgets. Comparison of ttk and Toykinter widgets.
-
-
-
Continuing the process of trying to pin down what an assertions dialog is, what it should do, and how its data should be represented in the interface.
Specifically in this video: Assertions as the link between evidence and conclusion are a big part of the Treebard philosophy. Existing genieware allows sourcing but it's tedious to do, and only a few evidence-based geniewares recognize the existence of the assertion. Difference between multi-person events and adjunct roles. What to do about roles and notes in the assertions dialog. Conclusions table inputs detect edits and save them in the database automatically. Why rows and cells in the conclusions table are the same color as the background. Starting a do list for the assertions dialog. Big vs. small in GUI fashion. Inputs needed for citations, sources, roles & notes. Creation of Toykinter autofill spurred by fear of Stack Overflow's critics. Citation input should be an autofill.
-
-
-
Continuing the process of trying to pin down what an assertions dialog is, what it should do, and how its data should be represented in the interface.
Specifically in this video: Threatening to jump in and write some code without planning first. Tired of fake data, want to create a real family tree with Treebard. Name source documents consistently so they can be sorted. Intro to the question of whether Charles D. Gregory is really Charlie Hilton. The three source documents on Charles.
-
-
-
Continuing the process of trying to pin down what an assertions dialog is, what it should do, and how its data should be represented in the interface.
Specifically in this video: SQLite dot commands such as `.schema`. What columns are in the `claim` database table. Primary keys and foreign keys. Dates should be text, not integers. Column constraints and default values. Use the same kind of primary keys throughout the database. Name tables and columns consistently. Numbers and dates on a patent paper, where to put it all. Citation table should not have a separate column for each item such as chapter, page number, line number etc. Manually entering data in source, citation and repository tables. Different ways to do `insert` queries. Complaint about the English language. Making an `update` query to correct data in an existing row.
-
-
-
Continuing the process of trying to pin down what an assertions dialog is, what it should do, and how its data should be represented in the interface.
Specifically in this video: Bring back Windows 7 photo viewer instead of using the one that comes with Windows 10. Inserting records for the third and last document we have that mentions Charles. Snatches of tales from the olden days back home. Continuing to input data manually, deciding what to enter, trying to decide what is an event vs. a document granted. Is the document also an event or is it just a source? Hitting a barrier indicates the need to stop and make a design decision.
-
-
-
Continuing the process of trying to pin down what an assertions dialog is, what it should do, and how its data should be represented in the interface.
Specifically in this video: Should several many-to-many tables be combined into the links_links table? In a boolean column, SQLite uses 0 for False and 1 for True. Questioning whether an assertion is a single thing or a compound thing like a row of details about an event. If the hypothesis is wrong--that assertions are the natural way to link conclusions with evidence--then Treebard will change its focus in that respect.
-
-
-
This should be the end of the thought process leading up to writing some actual code for the assertions dialog.
Specifically in this video: A revolution in thought has taken place within the past day. An assertion is not a whole row of factoids describing an event or attribute, it is one factoid. The assertions dialog will not look like the conclusions table. Ready to admit that the double-naming of finding/conclusion & claim/assertion is a nuisance. Some parts of the conclusion table are like keys which define the topic and other parts of the conclusion table are like values detailing that topic. Planning to put a tabbed widget in the assertions dialog with each tab corresponding to a values column in the conclusions table.
-
-
-
This is the first video on writing some actual code for the assertions dialog.
Specifically in this video: instantiating a Toykinter TabBook instead of a ttk.Notebook. TabBook's arguments. Toykinter routines for subclassing Tkinter widgets. Accomodating the Toykinter configurable hideable scrollbar. Adding text to a label with wraplength option. Changing the minimum size of the TabBook.
-
-
-
sizing the TabBook widget. Relationship of conclusions to what's in the assertions dialog. Reviewing the columns in the finding table. Using default values for database columns to avoid null column values. Things to do before dropping a database table. Running SQL commands safely inside a transaction with `B` and `COMMIT`. Renaming a table and some of its rows by copying the table and inserting data from the old table. Various copies of the default database within the file structure of the app.
-
-
-
moving the columns from the small many-to-many tables that deal with assertions into the general many-to-many table `links_links`. Adding a new column to an existing database table. Repeat exact names of primary key columns whenever possible when creating foreign key columns. Why lots of developers prefer to not use things like `ON DELETE CASCADE` in their table schemas. Two ways of making a foreign key. Why SQLite is being used instead of postgreSQL. Why Treebard wants to be a portable program.
-
-
-
adjusting the Python code to accomodate the changes just made in the database table and column names. Telling Notepad++ where your default directory is. Finding every occurrence of a just-changed variable in the whole app and deciding what to do about it.
-
-
-
deleting a column from a database table. Deciding for each column involved whether it's going to be used in a one-to-one, one-to-many, or many-to-many relationship. Understanding that there are two kinds of data in the assertion table; with each assertion representing one detail of an event or attribute, only one of the four detail columns can have a value in each row. In a one-to-many relationship, the foreign key for the "one" goes into a column in the "many" side of the relationship. Surety levels for the various assertions that are linked to the same source are independent from each other. Every assertion has to be linked to a citation even if the source is "my imagination". Adding foreign key columns to a database table. Since conclusions and assertions are optionally linked, the finding_id column in the assertion table can be null.
-
-
-
new arrangement of the global database and the tree database. How to attach both databases to the same connection. Why I got rid of AUTOINCREMENT from the primary keys. New way to get the ID of the last row created in a database table. Details of the new places functionalities. Adding event types so more specific assertions can be recorded. Adding citations and assertions.
-
-
-
Conclusions are linked optionally to assertions. Closer look at the columns in the event type database table. Adding event types and citations. Cardinality (one-to-one, one-to-many, many-to-many relationships among data.) In the assertions table, some columns identify the event or attribute and others provide details i.e. assertions about specific details such as date, place, age, particulars, and maybe name. Each row in the assertion table is for one assertion about one detail. Adding assertions to the database manually. Storing dates in the database as dash-delimited strings. Demonstrating the new place feature for creating a new nested place made of four other places.
-
-
-
Inserting more assertions to the database manually and making corrections by updating existing rows. My experience trying to get copies of patent application files from the patent office.
-
-
-
Discussion of the assertion dialog's goals. Linking conclusions to assertions. Getting the sources count to display on the SOURCES button for each row in the conclusions table of the GUI. Tracking the code flow to find out where a mistake was made in defining a value.
-
-
-
Analysis of the goals of the assertions dialog in terms of what sort of data is represented in each column of the assertion table in the database.
-
-
-
Writing the code for the assertions table that will appear in each tab of the assertions dialog. Making the top (header) rows for the assertions tables. Adhering to current GUI fashions, trends, and fads is not one of Treebard's goals because Treebard is here to stay and we don't want to rewrite Treebard to keep up with fashion. Using a nested loop to create multiple tabs in a tabbed widget with a table in each tab which all have the same column heads. Looping through Python dictionaries.
-
-
-
Using the Toykinter Separator widget. First step in designing a complex dictionary is to type out a mock example of what the dictionary will look like when finished. Since names are more important and more complex than attributes, they don't fit in the conclusions table, so conclusions about names will go in the names tab. Choosing between indexed collections like Python lists or keyed collections (Python dictionaries). To get tab traversal order right when creating a collection that will be used to create a table in the GUI, make sure that information flows through one row at a time, i.e. row by row instead of column by column. In Treebard, any note can be linked to any number of other elements so that notes don't have to be copied.
-
-
-
An empty model for the inner dictionary of the nested collection that will store data about assertions that back up one row or "finding" on the conclusions table. The inner dict will be repeated for each row in the assertion table in each tab on the assertions dialog. Using a tuple as the second argument in Python's method cur.execute() when running SQLite queries. Turning on foreign keys in SQLite 3. Building up the required compenents of the envisioned Python dictionary. Trying not to get carried away when nesting loops in Python.
-
-
-
Assigning variable names all at once by unpacking a tuple from database results. Trying to add a column for role IDs in the database assertion table, but finding that a review of the data structure for storing roles is needed.
-
-
-
Roles are details in the assertions dialog. How roles are structured differently from other elements of genealogy. Review of changes made to database structure to accomodate roles. Button added to unlink an assertion from a finding. Review of nomenclature. How assertions are linked to roles vs. how findings are linked to roles.
-
-
-
Review of the main dictionary used to save the values that will be used to make the assertion tables in the assertions dialog. Avoiding looping and indexes by unpacking a tuple to create several variables at once. Why I talk funny. Using explicit variable names instead of codey ones so the code is more humanly readable. Printing values to get oriented
-
-
-
Don't always use Python printings in place of thinking, but in those cases when you can't think, print something anyway. Typical mistakes detectable as loop design errors.
-
-
-
Debugging with print because of brain fog. Assertions not linked to the current finding do not appear in the assertions dialog. Manually linking assertions to findings in the SQLite console. Different kinds of zero values for different data types. Double-checking printed values against values stored in the database. Converting IDs from the database to their corresponding display values using JOINs in the SQL queries. Converting a tuple to a list. Getting the right name to display for a person who has no birth name.
-
-
-
How Treebard gets the right display name out of the database from a person ID. Determining where values came from and adding parameters to an existing class to get those values to somewhere else in the same way. Doing it wrong the first time doesn't save any time. Converting a storable date string to a formatted date string for display. Determining at what point incorrect data went wrong. Treebard never stores or displays months as numbers except in the unknown date string "-0000-00-00-------". Getting a nested place name from a nested place ID. SQLite's `cur.fetchone()` returns one tuple of values while `cur.fetchall()` returns a list of tuples. Using a list comprehension to change query results to a list while omitting unwanted values. Using Python's `join()` method to turn a list into a string.
-
-
-
Manually adding roles and persons to the database in the SQLite console. In Treebard, role persons are tracked equally as family persons. Adding a new role type manually. Assertions and conclusions about any given element of genealogy are not the same thing and don't have to have the same value. Converting role type ID and role person ID to role type string and person name. Attaching two SQLite databases to the same connection.
-
-
-
What Treebard is for, and what assertions are good for including a real example. Features that the assertions dialog will need. Instead of replacing IDs and other storable identifying versions of the needed data, the identifiers have to be stored too, along with their corresponding display values. Designing a better storage collection by adding data manually to a pseudocode example so the goal can be visualized before trying to write the code. Discussion of whether or not to store the names of the widgets in which the data are displayed, in case the data is edited.
-
-
-
The dictionary used to save data for the assertions table only needs to save values relevant to each tab in that tab's part of the dictionary, and not the blank values. Unpacking tuples of query results to avoid multiple re-readings of the tuple to find indexes. Using CTRL+Z (Undo) several time in Notepad++ as a quickie rollback. Creating a dictionary of wanted items while looping over a list that contains both wanted and unwanted items. Adding an Assertion column to each tab so that the detail type handled by that tab will have its value displayed as an assertion. Keep returning to the goal when trying to decide what code to write. The name displayed in the name tab of the assertions dialog is not the general display name of the current person, but the specific name string associated with the name ID that's stored in that specific assertion in the database.
-
-
-
When do good globals go bad? Creating a copy of a model dictionary without allowing changes in the new dict to leak back into the original model. Adding something to a collection while looping over a copy of the collection, returning its new value and doing all that in a loop, once for each tab.
-
-
-
Determining how and where to save a transient value during a loop so a needed value will not be overwritten every time the loop runs. Treebard does not combine assertions that say the same thing; all assertions are needed in order to weight the evidence that the assertion is right or wrong. The right time to save a value is when the value is right. Wondering whether the code structure being used could be simplified or rewritten in a simpler structure. Trying to figure out where the loop is wrong by changing one thing at a time.
-
-
-
Using a local list to save valid values in a loop that would otherwise be overwritten by the next iteration of the loop. Pasting output results to a text document so the output can be rearranged and made easier to look at. Using Python's `dict()` method so a dictionary modeled on a first dictionary doesn't propagate changes backwardsly to the first dictionary.
-
-
-
Saving values symmetrically to avoid too many conditional tests later. Once the first loop produces correct values, the rest of them are worked out quickly by repeating the same pattern of code over and over. Musical interlude with a rousing medley of one-liners from Ray Stevens songs.
-
-
-
A column for event type needs to be added to the assertions table. Where to get the rest of the values needed to fill out the rows in the assertions table of the assertions dialog. Separate code is written for different types of things so the code is easier to understand, even if it makes the code a little longer. Better to write a new procedure than to ruin one that already works by trying to make it do two different things.
-
-
-
Adding notes to the database manually and linking them to assertions. Adding another column to an existing select query's results table. Two or more functions are better than one super long function. To change a Python dictionary while looping over it, loop over a copy of it while changing the original. If there will only be one result or one tuple of results from a select query, use `cursor.fetchone()` instead of `cursor.fetchall()`.
-
-
-
Loop over the right number of things in the right place and make sure you have the values you need when you do it. Planning the next immediate steps. If you're too tired to think or see, turn off the computer.
-
-
-
Testing for None to avoid errors. Revisiting the goal. Getting text columns from the database that correspond to IDs. Saving altered code blocks as comments until the new version has been tested. Using consistent naming conventions so database table names don't have to be memorized or looked up. Joining two tables in a select query to get results from both tables in a single query.
-
-
-
Adding source, citation, and surety to the main dictionary that's used to create the assertions dialog. Looping through a list of dictionaries. Storing data retrieved from the database in a list of dictionaries in a way that will be useful in attaining the goal. Weighing the advantages of imposing symmetry so later in a loop all items being looped over will be structured the same. Checking the eventually-created dictionary values manually against the values in the database. Connecting to two databases at the same time. Displaying output readably in the SQLite console. Planning how to get notes data into the dictionary.
-
-
-
Deleting an extraneous column from the query results table. SQLite doesn't use the double equal sign. Delete extraneous calls to Python `print()` as soon as they're not needed. Some formatting of the assertion table area in preparation for creating the table cells and displaying the values saved in the dictionary.
-
-
-
Treebard's autofill inputs. Starting the code that will create the cells in the assertion tables. Trying to decide where to run the function that makes the assertion tables, since running it before the dictionary has its values won't do any good, but currently the header row on the tables are created before the dictionaries are populated with values.
-
-
-
The simple code used to assign column and row indexes to the cells in the assertions table. Getting the right text values out of the dictionary and displaying them in the correct Entry widgets. Tkinter formatting to get column cells and column headers to line up right. Adding spacing between columns.
-
-
-
Changing some of the assertion table cells to Buttons and Scales. Options for the Scale variable. Demonstration of what happens to old people who sit in chairs too long and don't get enough exercise.
-
-
-
Tkinter Scale options. Treebard's ability to recolorize the whole app instantly when the user chooses a different color scheme is based on inheriting from Tkinter widgets. Discussion of Tkinter's Button widgets, ttk.Button, and Treebard's special buttons made from a Label widget. Discussion of the purposes and related purposed of the various columns in the assertions table. Treebard assertions and conclusions are concretely separate. Looking for ideas on StackOverflow. Outlining what's envisioned for making a better way to display the Scale's changing value.
-
-
-
Setting the opening value of the Scale widgets based on the values stored for each assertion in the database. Designing a tooltip to display the value of the Scale or surety slider as the user changes it.
-
-
-
Summary of what was done in several deleted videos wherein progress was so slow that the videos became unwatchable. Tkinter event bindings and callbacks. Identifying what does and doesn't work on the surety slider so far, and figuring out when the error is triggered. Exploring whether to fix the partially functioning code or try a different approach.
-
-
-
Defining the tooltip's opening value earlier so it will exist when the dialog opens and the tooltip will display as soon as it's needed. Defining and prioritizing goals as functionalities slowly improve for the surety value's tooltip. Determining when and why a value became incorrect. When values are correct in a loop but keep getting overwritten by the next value in the loop, they have to be saved while they're correct so they can be referenced later.
-
-
-
In debugging the GUI code we find out when the value is correct and at that point get the value to where it's needed. Finally the surety tooltip value starts, updates, ends, and restarts correctly.
-
-
-
Demonstration of Treebard tooltips' ability to decide for itself whether to appear below or above what the mouse is pointing at. Discussion of Tkinter's Button widget vs. Treebard's LabelButtonText widget. Adding text to a button only while the mouse pointer is over it. Psychology of GUI design. Trying different Treebard button classes to see whether a new class needs to be made.
-
-
-
Creating mouse hover events to show/unshow button text by binding the button to Tkinter's Enter and Leave events. To pass other parameters besides the obligatory `event` parameter with a Tkinter callback, a Python lambda is used. Adding a second callback to a widget using the same event that's already bound a different callback to that widget. Treebard's LabelDots class is used to open the Notes dialog.
-
-
-
To use the LabelDots class, a model of how it's used elsewhere is copied and modified to work in the assertions dialog. Thinking of the best short word for the header on the column of buttons which will cause the assertion to be copied to the finding that the assertion is linked to.
-
-
-
Using Python's `dict.get()` method to avoid an error if there are no notes stored in the dictionary. Saving different kinds of data in similar ways within a given collection so that when looping over the collection, each loop looks for data in the same way ("symmetry"). Considerable time wasted using too much printing for debugging where the only thing wrong is that nervousness/camera allergy/old age/senility is causing me to forget things. Making plans to start the next phase which is updating the database when the user changes something in the assertions table.
-
-
-
Which of the assertions table cells are going to be autofills. Displaying both parts of the assertion in the assertion column of the roles tab. A separate strategy is needed for saving changes in the surety column since they can be used by the mouse when they're not in focus. Using a boolean variable to tell Treebard whether or not there are changed surety values to save when the assertions dialog closes. Using Tkinter's `wait_window()` method to run code that should run only when the dialog closes. Looping over only the values in a dictionary. Trying the Tkinter Configure event to trigger adding surety slider values to a dictionary.
-
-
-
Changing the Tkinter event that records Scale values to the ButtonRelease-1 event. Adding values to a nested dictionary. Passing values with a lambda. Updating the database with values saved to a nested dictionary.
-
-
-
Considering what should happen when the UNLINK button is pressed on an assertion table row in the assertions dialog. Looking into making the Scales take focus so the sliders can be moved with the left and right arrow keys, and deciding it's not worth the trouble. Don't pass the database connection & cursor from a binding lambda callback, a custom connection is needed in the callback itself so the connection will be live when the callback actually runs. Unlinking an assertion from a finding by deleting one foreign key from one column in one database table.
-
-
-
Tentative plan for showing the source's repository as a tooltip when hovering the source column. Purpose of Treebard GPS. Debugging the display of the role person in the assertion column of the roles tab. Writing a conditional statement to deal with an exception to the attempt to create symmetrical collections.
-
-
-
Considering the alternatives to redrawing the whole assertions table when an assertion is unlinked from the current finding that the rest of the dialog is about. Using Tkinter's `grid_slaves()` method to get a list of all the widgets in one row of a GUI table. Disabling a row of widgets instead of redrawing the table without the row is easy but apparently the LabelButtons still respond to their mouse click events, so the bindings will also have to be removed.
-
-
-
What is "chapter one of Treebard development". The I-shaped mouse pointer has been changed so is now visible in these videos. Changing the resolution, length and sliderlength options on tkinter.Scale. Disabling vs. destroying widgets in a row of the assertions table after unlinking that assertion from the current finding. Mistaken reference to LabelDots widget so ~14:20-19:19 can be skipped. Changing the text on a button in the main window by pushing a button in a dialog. Bird calls and chickens crowing 24:20-25:55.
-
-
-
A 40-minute segment just prior to this was lost due to a crash of Windows caused by something in the code, which triggered a brainstorm: why not destroy the unwanted widgets when unlinking an assertion from a finding, instead of disabling them? Keeping the data stored in the database whole by manually undoing tests frequently in the SQLite console. Trying to decide what should happen in regards to window resizing when an assertions table's values get blanked out and it tries to shrink down too much. Long discussion of Toplevel window geometery, window resizing, scrollbar resizing, and how this relates to TabBooks which should have a minimum size and should not resize at all (~10:00-end, somewhat confusing and inconclusive so could be skipped, but should be watched by true Treebard devotees).
-
-
-
In the current video I was pushing the pause button too soon over and over, which is why it sounds badly edited. Nothing of substance was lost, it's actually not edited at all. The (deleted) prior video was another 8 minutes of confused babbling and dithering about scrollbars and resizing and how that relates to a TabBook in a dialog. The solution for now was to follow the instructions I'd left for myself in the wake of previous stabs at similar problems: set the minimum size of a TabBook to accomodate what it's meant to contain, and then the scrollbars should work as expected. Getting rid of the second label in the title bar. Treebard is not trying to work for small screens; that's not our goal, so the assertions dialog can be big if it needs to be. Discussion of the importance of repositories and how to display them in the GUI. Thinking out loud about the relationships and cardinality among sources, citations, repositories and assertions. A new table needs to be added for locator, which is for example the call number if the repository is a library, or a URL if the repository is a website. Collecting repository references (locators) to add to the database.
-
-
-
Discussion of the Treebard project. Figuring out the cardinality of the relationship between contacts and repositories by considering some examples. Removing an unwanted column from a SQLite database table. Arguments for Python's `range()` method. Using the `weight` argument of Tkinter's `columnconfigure()` method. Applying exactly the same padding in the table header as the table cells so the columns will line up with the headers.
-
-
-
Different ways to update the Python dictionary that is used to create the assertions dialog, whenever an assertion is unlinked from a finding. Review of how the assertions dictionary is structured. Deleting an item from a Python list. Rereading yesterday's decisions on cardinality among source, citation, assertion, locator, contact and repository to catch any lingering errors in thinking.
-
-
-
In this series of videos, I'll select a real family tree to try and create from scratch, while at the same time demonstrating or summarizing the process of building a new Treebard feature from the bottom up. The feature I'll be adding is the Assertions & Sources Dialog that opens when you click a SOURCES button in a row of the conclusions table on the current person tab. Also pictured in this video is my forum or blog.
-
-
-
Wondering whether source types might be needed after all. Considering the role of locators within repositories vs. citations within sources. Mulling over and correcting the use of citations to keep track of separate documents and other citables, versus using separate citations to delineate separate events. Treebard's goal is to match the level of complexity of the data it's trying to record, not to be too complicated or over-simplified. Manually adding some locators to the database.
-
-
-
Adding the repository buttons to the new REPO columns in the assertion tables. Momentarily stumped as to why the dialog seems to have a maximum size, to be continued.
-
-
-
Summary of Treebard dialogs. Creating a placeholder for a repositories dialog with just a Toplevel and Label widgets. Comparison of Treebard and Windows title bars. Plans for the CONCUR button. Discussion of which of the data displayed on the assertions table should change on pressing the CONCUR button. Treebard is equally useful for sourced and unsourced trees because the user forms his own conclusions no matter what the assertions say. Conclusions are linked to assertions but there is no code influencing the conclusion; the conclusion is entirely up to the genieware user. CONCUR button should be right next to the assertions column and the assertions column should be the first column.
-
-
-
Moving columns around in the design of the assertions tables. Making the minimum and maximum size of the dialog the same got the horizontal scrollbar to work acceptably if the minimum size is big enough to show the content in the biggest tab. Looking at putting the assertions dialog content into the main assertions tab instead since it has gotten so big, and since the assertions tab has no logical content other than the assertions linked to the current finding anyway.
-
-
-
The remark that "...assertions and sources have a one-to-one relationship..." was not meant to be taken literally; the underlying fact is that each assertion is linked to one citation (although one citation can be linked to multiple assertions). Plans for an assertions dialog will be changed to an assertions tab in the main TabBook instead. Other examples of TabBooks (like the assertions TabBook) that are inside other TabBooks. Finding and adjusting/deleting variables that will be affected or neglected by the change from dialog to tab. Determining which methods need to be run in a different way since there will no longer be a dialog closing to trigger their execution. Programmatically making a certain tab in a TabBook the active tab.
-
-
-
Getting content to appear when it doesn't show up. Juggling widgets in the available space to make the GUI look good. Planning the next steps.
-
-
-
More GUI design for the new assertions tab. Dynamic text for a label. Adding a Tkinter Frame to help achieve design goals. Use of space and positioning in GUI design. Thinking about what the SAVE CHANGES should and should not be responsible for. Programmatically opening a different tab.
-
-
-
GUI design changes to make the layout as efficient and attractive as possible. Telling Tkinter which column should expand into extra space with `grid_columnconfigure()`. Changing the order of tabs in a TabBook. Creating, deleting, and moving columns in the assertions tables of the assertions tab. Constructing a column of Tkinter Checkbuttons. Tkinter's Checkbutton has way too much space around it for use in a table row; no way is found to change this very much. Making borders in Tkinter. Discussion on how current trends in GUI design, heavy with thumbnails, give websites a comicbook-like appearance with too much vertical scrolling needed to get the big picture. Planning how to make a Toykinter Checkbox to use instead of Tkinter Checkbutton. More desirable features of Notepad++ vs. other text editors. Making a rudimentary Tkinter app in a Python file.
-
-
-
This video and the next will comprise a mini-series on making a custom Toykinter Checkbox widget to use in place of the Checkbutton widget that comes with Tkinter. To go straight to the assertions dialog code, just skip these two videos. Demonstration of some of the Toykinter widgets that have already been made for Treebard. Using `if __name__ == "__main__"` in Python. Treebard's routine for inheriting from a Tkinter class in such a way as to make the subclass detectable. Mocking up a Treebard `formats` dictionary. Using Tkinter's `pack()` geometry method for very simple layouts is easier than using the `grid()` method. Sizing and positioning a Tkinter toplevel window with the `geometry()` method. Treebard color schemes. Getting a Label to take focus. Binding a widget to `FocusIn`, `FocusOut` and `Button-1` events in order to toggle its color when tabbing through it.
-
-
-
This video and the prior video comprise a mini-series on making a custom Toykinter Checkbox widget to use in place of the Checkbutton widget that comes with Tkinter. To go straight to the assertions dialog code, just skip these two videos. Binding a Label to a mouse click to dynamically display text in the Label. Adding inner padding to a Label between the text and the edge of the Label. Tkinter `StringVar()` and the Label's `textvariable` option. The Label's `text` option can't be configured with the `configure()` method if the `textvariable` option is used with the Label. Toggling a Label's text on and off with mouse and key press events. Adding a function in the app to prove that the Checkbox can be used. Looping over values of Tkinter variables stored in a dictionary. Adding a new Treebard widget class in widgets.py so the color scheme functionality will work with it. Python class-level variables vs. instance-level variables.
-
-
-
Adding the new Toykinter Checkbox to the assertions tables in the assertions tab. Clarifying the goal. Writing a temporary method to prove that the Checkbox values can be accessed and used in the assertions tab. Catching up on needed database connection code updating in colorizer.py since some changes had been made a while back. Troubleshooting recent addition of colorizer code for the new Checkbox widget in widgets.py. Details about the colorizer code. Getting the assertions tab and its child widgets to colorize correctly by manually adding a string to a tuple in widgets.py. Figuring out whether or not the AssertionsTab class has to be moved to widgets.py.
-
-
-
Redesigning the functionality of the unlink procedure so that it doesn't take effect immediately when the change is made and doesn't immediately delete the unlinked assertion's widget row from the GUI. Finding a new way to pass a Python value when the old way doesn't work anymore due to changes in the procedure's design. Using a nested function for an inner loop instead of nesting loops, so that `return` can be used instead of `break` (since `break` would only work on one of the nested loops). Deciding whether to add more values to the main dictionary or create a smaller dictionary for a special purpose. Considering whether to use the `cget("text")` method instead of using a textvariable to get the Checkbox label's content.
-
-
-
Getting rid of the `textvariable` in the Checkbox class so the simpler options and methods that come with Tkinter Label can be used instead of having to use `get()` and `set()` with a `StringVar()`. Finding an alternative to using a loop. Detecting the state of the Checkboxes when the user presses SAVE CHANGES so the changes can be saved to the database.
-
-
-
Suspecting that a new assertions table is being gridded on top of the old one every time the SOURCES button is clicked. How to prove that and what to do about it. Tracing the code flow and fixing some odd things as they are found. Scouring the code to determine what has been made the parent of what, in order to find where an extra set of widgets is being made each time the SOURCES button is pressed; this will tell us where the old assertions table is so it can be destroyed instead of gridding a new one on top of it.
-
-
-
Still trying to figure out what is the parent of the theoretically multiplied widgets that need to be destroyed so one assertions table is not gridded on top of another every time a SOURCES button is pressed. Saving a snapshot of every module that was changed today in the process of solving this problem. What is the next problem to solve.
-
-
-
Said "showcase of personalities" but meant "showcase of functionalities". Discussion of why the CONCUR button has more con than pro, so will be eliminated. Eliminating the CONCUR column from the assertions tables. There has to be a clearcut distinction between what conclusions are and what assertions are. Review of what the other columns will do.
-
-
-
Why assertions table widgets aren't being saved in the main assertions_data dictionary. Treebard's general strategy for updating the database as soon as the user tabs out of an autofill entry if the content of the entry was changed. Starting the repository dialog feature (which will continue through episode 119 of this series). A little information on Tkinter's `unbind()` method. Where to copy Treebard code to get what's needed for a scolled dialog consistent with Treebard's other scrolled dialogs. Details on Treebard's (Toykinter) Border class. Brainstorming the design considerations of the repository dialog.
-
-
-
There will be some discontinuity between this video and the previous one since I deleted the eight videos prior to this one. In the deleted videos, I had written code to show contact data related to repositories in the repository dialog. Fake data (Mickey Mouse etc.) was used. Finally I realized I was writing an address book and not a repositories tab. In this video, the turnaround is planned and the new direction is taken. Adding another tab to the main TabBook. Trying to delete the right amount of code and read what's left to determine where and how to start on the new goal.
-
-
-
When making a big change to some coding goal, don't always just try to adapt the old code to the new goal. Often it will be better and easier to delete the old code and start over with only the new goal to be concerned with. Using a tuple as a key in a Python dictionary. Earthquake interlude. The difference between SQLite's `cursor.fetchone()` and `cursor.fetchall()`.
-
-
-
Creating the desired useful nested collection with a nested loop. Using the Toykinter MessageCopiable which looks like a multi-line label but is inherited from a Text widget so its text can be highlighted and copied, allowing it to be used for long references such as URLs. Troubleshooting the collection used to store repository data. Recognizing a flaw in the data structure relationships.
-
-
-
Preliminary fine tuning of the logic used to select related data from the database (more corrections will come in a later video). New schema for locator table was created "yesterday" (videos made yesterday probably won't be uploaded). Changing the Python code to reflect changes made in the SQL queries. Converting data to the right data type to fit the requirements. Designing the GUI from the perspective of the user and what the user needs or expects.
-
-
-
Planning which assertion details will be displayed in the repository dialog and how to display it. Breaking out of the inner loop in a nested Python loop using a separate function. Presenting complex data as simple and palatably as possible in the GUI.
-
-
-
Using a conditional expression to deal with a case where data had to be stored in an unsymmetrical manner. Pressed STOP instead of PAUSE so this was a short movie.
-
-
-
Inserting a Tkinter Frame into an existing GUI and making the necessary adjustments to the code. Updating some database connection code since the database was recently split into two databases and there are still a few lingering loose ends to tie up. Brainstorming on which data should be used as values in a combobox dropdown list. Using `return` to halt a Python function if the needed data input is blank. Using the Toykinter Combobox widget class.
-
-
-
Adjustments to the GUI design. Increasing the width of the Toykinter Combobox dropdown; preliminary troubleshooting of this attempt. A complex hack created as a workaround for a deficiency of the Toykinter Combobox code. The difference between Tkinter's `grid_forget()` and `grid_remove()` methods. Trying to make a spacer (with the wrong kind of widget; will be corrected in a later video). Trying to make a spacer with pad-and-hack (will be corrected in a later video).
-
-
-
Identifying a new source and repository to input to the database with the GUI, once the code for doing that is written. Manually inputting the new citation to the database so the GUI can be created and used for inputting the new repository where that source was found. Manually inserting a new row to the database assertion table. Recurrence of a Combobox error that had been temporarily hacked into submission once before in a different situation. Getting repository values for the autofill entry input. Using the EntryAuto class' `create_lists()` method.
-
-
-
Another workaround attempted since the Combobox error has returned. More combobox confusion ~11:00 - 20:15. Cross-pollution of data and focus noticed with more than one non-modal repository dialog open at the same time. Mostly combobox confusion ~27:00 to end. Decision to make a separate RepositoryDialog class.
-
-
-
Moving the repository dialog code out of the AssertionTab class into a new RepositoryDialog class in a new module. Recognizing the need for a class level variable so all instances of a class will have access to the same values. Treebard's naming conventions for the two main methods repeated from class to class. Using instance variables instead of passing parameters. Figuring out which parameters the new class needs.
-
-
-
Continuing to adapt the working code from the former version of the repository dialog to its own class. What happens when you try to save time by pressing REPLACE ALL in the FIND AND REPLACE dialog. With the repository now being successfully created as a class instance, the combobox error which had been hidden by hacky means twice before now rears its ugly head in a third situation. It's time to fix the Combobox class insted of hacking away at its instances.
-
-
-
Getting rid of the default text in a combobox before the text ends up being saved in the database. Ready for the final confrontation with the repeatedly surfacing combobox error which is not well understood. A problem with using a class-level variable for locator values in comboboxes. Problems with the logic being used to select locators per repository (will return to this in a later video). More fishing around for what's wrong with the combobox (the real problems have not been spotted yet). It is finally realized that the only thing wrong with the Combobox is that it's inappropriately giving itself a scrollbar when it only has two values to display in the dropdown. This opens up the further realization that hacky fixes on the combobox at the instance level have created further problems. Demonstrating a known slight defect of the autofill entries. Shooting at the Combobox in the dark. More trial and error with Combobox dropdown height and scrollbar configuration ~36:00 to end. Noticed the difference between when autofill replaces highlighted text and when it doesn't. Finally it's decided that the combobox dropdown's scrollbar problem is not fixable by fooling around at the instance level; it probably existed all along and was never noticed since this is the first time I've tried to dynamically change the values of a Toykinter Combobox; so the Combobox class itself has to be somewhat refactored/repaired.
-
-
-
Musical interlude #1. Simplifications and repairs have been made to the Combobox class with the camera off, solving the problem with the dropbox height and scrollbar appearing in the dropdown inappropriately. (Important side note: according to one source, Motorola introduced car radios around 1930.) Charles Gregory summary and announcement of the next video series to come after this one. Musical interlude #2. Features of the Toykinter Combobox that Tkinter's ttk.Combobox does not have. Miscellaneous changes that were made with the camera off.
-
-
-
Specific changes that had been made to the code while fixing the Combobox class while the camera was off. Trying to figure out why a previous unused choice blanks out of the Combobox entry when tabbing out of the repository input, and how to fix the problem.
-
-
-
Replacing the variable padding hack with a permanent spacer frame. Approximating a variable frame height by varying the frame's height with the font size chosen by the user. Understanding better what the code is doing so it can be made to do something slightly different.
-
-
-
Trying to put default text in the locators input combobox. Putting the selected locator into the database. Need to get the ID corresponding to the selected locator so it can be put into the database. First the right locators have to be given to the combobox, which has been done wrong from the start. Clarifying what locators are for and why a repository might need to be added using the repository dialog. Why these edge cases need to be handled by Treebard. Bringing back the many-to-many relationship between source and repository, and using it correctly this time.
-
-
-
Writing a select query to get repository and source foreign keys from the links_links table. Trying to figure out what to do and when to do it in regards to inputting a new repository and a new locator within the repository. Inserting many-to-many links between sources and repositories. Using a SELECT COUNT query to get a sort of yes or no question answered from the database.
-
-
-
Testing to make sure extraneous query results are no longer being gotten. Writing the insert queries and testing the results to get new repositories and locators into the database on a press of the OK button. As predicted, the default text from the combobox ended up in the database and caused a time-wasting error. Finding the right time to run the insert query to input the new locator to the database.
-
-
-
Messing around with the default text again. Because of the complications involving the use of Tkinter's `focus_set()` method, it's decided to not use default text on the combobox. A label will be created and destroyed at the same time the combobox is created and destroyed. Using Tkinter's method `wait_window()` with a Python boolean to put the new locator into the database when the OK button is pushed to close the dialog, but not if the CANCEL button is pushed to close the dialog. Figuring out when and where to get the value out of the combobox, after the combobox has a value but before the combobox and/or the dialog destroyed.
-
-
-
Using a label instead of default text in the GUI to inform the user what the combobox is for. The repository dialog is finished for now.
-
-
-
Review of progress so far and next steps to finish chapter one of Treebard development. First look at the notes dialog and its functionalities. Getting some old problems solved in the notes dialog.
-
-
-
Adapting the notes dialog to work with the assertions tab although it was custom-designed to work with the conclusions table on the person tab. Remember to look at the class to see what the parameters are.
-
-
-
Basing new code for notes linked to assertions on working code for notes linked to findings. Don't make dialogs modal unless they have to be modal. Identify places where designing a new use for an old feature won't work directly without making some changes, since two uses for one feature involve different goals, expectations and needs, i.e. different reasons for using the feature.
-
-
-
Planning how to customize the notes dialog's header for two different parts of the application. In a place assertion, the place is the assertion itself; in a date assertion, the date is the assertion itself; etc. Pinning down the exact nature of the difference between the two applications of a single feature. Identifying places where the GUI design could easily be improved.
-
-
-
Tracing the flow of values through some slightly convoluted code in order to pass variables when and where they're needed. An example of how unsymmetrical code--(storing values in different ways in the same collection)--can lead to complication and extra work down the road. Simple changes in the GUI design can make a big difference in the GUI's visual appeal. It's not good enough to dynamically populate widgets with stored data; it should be the stored data that will help the user intuitively know what the GUI feature is to be used for, specifically. In regards to the notes dialog header, identifying the last holdout of built-in hard-coded inflexibly displayed data.
-
-
-
Concluding work on the header of the notes dialog, customizing the code so the header is relevant to assertions when opened from the assertions tables, but relevant to conclusions when opened from the conclusions table. The right stuff is not the right stuff at the wrong time. Tracking down and correcting some data that was manually entered incorrectly to the database (each assertion refers to only one detail e.g. name, date, place, particulars, age, or role). Calling out to Charles D. Gregory of Brownfield, Texas to be found. (Note: right after recording this, I got on familysearch and ACTUALLY FOUND HIM after searching for over 12 years.)
-
-
-
Updating the roles dialog Header to look like the new version of the notes dialog header. Preliminary identification of what method is supposed to display the missing note text in the notes dialog.
-
-
-
Getting notes to display when clicking a button in the NOTES column in an assertions table. How to use an event callback with or without binding to a Tkinter event. Since the notes dialog was made to be used with findings (rows in the conclusions table), it has to be extended to work with assertions also in the assertions tables. Adding boolean parameters to the notes dialog class so each instance of the class will know whether to use queries and other code specific to assertions or findings.
-
-
-
Using the notes dialog to make new notes. Parameterizing the situation where the existing queries from notes-to-findings links don't apply to notes-to-assertions links.
-
-
-
Testing the procedure for unlinking notes from elements. Extending the code once used with notes-to-findings links so it will work with notes-to-assertions links. Objection to saving note and note topic on FocusOut of either input.
-
-
-
What I didn't realize while making this video is that the `UNIQUE constraint` error was caused by tabbing out of the topic input when the topic of an existing note was in the topic input. This was a defect of trying to save notes on FocusOut instead of using a button. It was also not getting through to me that the note is not deleted from the `note` table in the database when the link is deleted from the `links_links` table. But I did correctly sense that the problem was trying to do something complex on tabbing out when the note and topic should be saved on pressing a button instead.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting the NotesDialog class and testing it to make sure it works equally with both findings (rows of conclusions in the conclusions table) and assertions in the assertions tab. Emphasis will be on 1) simplifying the code, especially to add a SAVE TOPIC AND NOTE button instead of the notion of saving new notes on focus out, and 2) totally reformatting the dialog so it's better organized, smaller and less klunky-looking.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting the NotesDialog class.
Redesigning the notes dialog on a simple grid so its main parts can line up naturally. Continued in next video.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting the NotesDialog class.
Lots of time spent making formatting adjustments large and small and trying to hunt down seemingly uncontrollable aspects of the formatting, all of which will eventually tracked down as this mini-series proceeds.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting the NotesDialog class.
In the case where you can't figure out which widget is creating an unwanted space somewhere, one strategy is to use FrameStay or LabelStay widgets to override Treebard's color scheme. When redesigning a GUI format, delete all the padding completely, and when the widgets are all in their respective rows and columns, positive weight has been added to rows and columns that need to expand into extra space, sticky and columnspan/rowspan have been set as needed, and spacer widgets have been added to keep large areas empty, only then add as little padding as possible and keep the padding simple.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting the NotesDialog class.
Correcting tab order in the notes dialog. Trying to solve the mystery of why the notes dialog is still working differently when linked to findings than it does when linked to assertions. This problem won't be solved till the next video, so all but the first few minutes of this video could be skipped.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting the NotesDialog class.
Finding the reason that the notes dialog displays differently depending on whether it was opened from the conclusions table or from an assertions table. The answer finally came when the two divergent dialogs were compared side by side. ~7:45 back on track, trying to unlink an assertion from a note. Changing some confusing names. Testing the ability of the existing callback, which is no longer executed by GUI `FocusOut` events, to unlink a note from an assertion when executed on a button press instead.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting and testing the NotesDialog class.
Testing more features of the newly rewritten NotesDialog class in conjunction with the assertions tables. Changing the order of topics displayed in the notes dialog's table of contents. A new note is made in the wrong tab; this will be corrected in a coming video. Minor corrections made to the dialog that lets the user change the order of the note topics in the table of contents.
-
-
-
Starting with video #122 and continuing through #129 is a mini-series on rewriting and testing the NotesDialog class. #130 will include a review of the notes dialog in its new condition by way of making a few final adjustments to its functionalities and formatting.
Using the Treebard interface to make a note private so it will not be included in any exports (the export feature has not been started). Making a widget disabled when the user goes to use it if certain conditions are not met.
-
-
-
Starting with video #130 and going through #135, cleaning up after the notes dialog rewrite and testing legacy methods in the notes dialog. To skip over this sequel to the notes dialog mini-series, skip ahead to #136 which will return to the assertions tab proper.
Cleaning up minor details from the recent mini-series wherein certain portions of the notes dialog had to be rewritten in order to get it to work with the assertions tab. Writing the code to link an existing assertion to an existing note. Questioning the usefulness of making a unique topic on each note the user's key to re-using that note, since the user will have to either remember or look up the note topic.
-
-
-
Starting with video #130 and going through #135, cleaning up after the notes dialog rewrite and testing legacy methods in the notes dialog. To skip over this sequel to the notes dialog mini-series, skip ahead to #136 which will return to the assertions tab proper.
Troubleshooting the final cleanup of the notes dialog and new features added to it in the last video. Making it impossible to link the same note to the same assertion multiple times. Finding untested features of notes dialog that haven't been touched on yet in the current rewrite.
-
-
-
Starting with video #130 and going through #135, cleaning up after the notes dialog rewrite and testing legacy methods in the notes dialog. To skip over this sequel to the notes dialog mini-series, skip ahead to #136 which will return to the assertions tab proper.
Quick test of the user's continued ability to unlink notes from assertions using the GUI. Getting the notes dialog table of contents to redraw when linking an existing assertion to an existing note. Making sure the functionalities of the notes dialog work from the conclusions table as well as the assertions tables. Reformatting the text on the button that opens the notes dialog depending on whether any notes are linked to the current element or not.
-
-
-
Starting with video #130 and going through #135, cleaning up after the notes dialog rewrite and testing legacy methods in the notes dialog. To skip over this sequel to the notes dialog mini-series, skip ahead to #136 which will return to the assertions tab proper.
Disabling the notes dialog's radio buttons if no note topic is selected in the table of contents. Binding focus-in events to the underlying frame/parent instead of its individual child widgets. In the notes dialog table of contents, highlighted and selected are not always the same thing. The formatting last hurrah on notes dialog, starting with conjecture which doesn't pan out. Setting the size of a widget to depend on the size of another widget (continued in next video).
-
-
-
Starting with video #130 and going through #135, cleaning up after the notes dialog rewrite and testing legacy methods in the notes dialog. To skip over this sequel to the notes dialog mini-series, skip ahead to #136 which will return to the assertions tab proper.
Dynamically taking into account border widths when matching Tkinter widgets to each others' sizes. Solving a stubborn problem by making a minified version so that there are fewer influencing factors to take into account. Displaying instructions in the assertions tab in case no assertions table has been chosen yet for display.
-
-
-
Starting with video #130 and going through #135, cleaning up after the notes dialog rewrite and testing legacy methods in the notes dialog. To skip over this sequel to the notes dialog mini-series, skip ahead to #136 which will return to the assertions tab proper.
Testing and updating legacy code in notes.py to fit with new changes, new features, and the new ability to work with either the conclusions table or the assertions tables. The notes dialog rewrite is finished for now. Planning the next goals in returning to the assertions tab proper.
-
-
-
Back to the assertions tab proper. Treebard's policy on complete lack of "smart software" influence between conclusions and assertions, leaving the genealogist in control of his own conclusions and the source in control of its own assertions. Making a callback that will update the database if the user makes a change to an assertion in an existing row of the assertions tables. @ 18:35 "mental hiccup about age" should have been "mental hiccup about name". Beginning to question the plan to store assertions about dates, names, places and role persons in standardized forms. Writing the code to edit assertions in the particulars tab and preparing to do so for assertions in the age tab.
-
-
-
Writing the code to edit age assertions and date assertions. Demonstration of how Treebard stores and displays dates in the conclusions table. Is this really how dates should be handled in the assertions table too? Making a date input that works like the date inputs in the conclusions table where the user can do free, simple input and Treebard will display dates according to the user's preferences. Changing a theme in Notepad++. Details on Treebard's date validation. Looking for more flexibility on configuring Notepad++ themes.
-
-
-
Looking at what would be involved in using the same standardized nested place string autofills in the assertions table that's used in the conclusions table. Questioning whether assertion inputs should be autofill places, formatted dates, and the like. Shouldn't all assertions be input freely as read exactly from the source, without interpretation or paraphrasing? Replacing the code for inputting formattable date storage strings as assertions with plain strings exactly as reported by the source.
-
-
-
It's not about me and it's not about Treebard, it's about the truth of genealogy, and that is: finding the truth about the past. Big changes made to the database assertion table schema so that no code or logic such as foreign keys will be used to determine assertion input or output, just unaltered user-typed data which is supposed to represent unchanged exactly what the source says. As the work proceeds, this philosophy will be enforced more and more strictly as more changes are made.
-
-
-
Updating queries that populate the assertions table since the database schemas have been changed so that all assertion details are stored as unformatted strings unaltered by code so that assertions can accurately state exactly what is said by the source.
-
-
-
Why the creator of Treebard can claim to "show the way" to other genieware developers in spite of his being a novice programmer. Review of changes that will have to be made to the main dictionary used to populate the assertions table. Simplifying the code to stop using foreign keys, formatting and autofill strings for assertion details. Making role assertion a simple user-input string like the other assertions.
-
-
-
Removing the code that stores date assertions in a standardized dash-limited format. Finishing and troubleshooting assertion edit functionalities in the various tabs of the assertions tab.
-
-
-
Treebard is not the new evidence-based genieware or the new conclusion-based genieware, it is genealogy finally reflected accurately in database software. Modeling the new event type input in findings_table.py to make the event_type input in the assertions table an editable autofill entry. Moving a function out of a class into the module-level namespace in a different module so it can be imported properly and used in more than one place.
-
-
-
Treebard can easily be used to do conclusion-based genealogy all or part of the time. Add edited event type changes from the assertions tables to the database. Making an error message in Treebard.
-
-
-
Putting the original text back into an event type input if the edited text is rejected by an error. When I said, "...decided not to deal with changing the event type..." I should have said, "...decided not to deal with changing to an event type that doesn't exist...". Writing code to make an autofill input for sources including the ability to make new sources on the fly.
-
-
-
Troubleshooting the code that gets the source to change in the database when it's changed in the GUI. Planning to open a source edit dialog if the user tries to change a source or a citation in an existing row of the assertions table. Using Treebard's Dialogue class to start making a small dialog that has no changing content and no scrollbar.
-
-
-
Changing the citation input widget to a combobox. Making a collection of citations per source to be used by all the citations comboboxes. Starting to get the values to display in the combobox dropdowns.
-
-
-
Troubleshooting the values inserted to the source and citation cells in the assertions tables. Getting the citation values for the combobox dropdown from the existing dictionary.
-
-
-
Planning the next series of videos in which the Treebard GUI will be used to create a family tree from documents in the order that the documents were found. Using the GUI to add birth event details to the conclusions table. Manually adding an age assertion and a citation to the database. Manually adding a repository and a locator to the database. Trying to open the source edit dialog, troubleshooting.
-
-
-
Rant about condescending robots trying to sound friendly. Adding an under-all frame for all the widgets so the unusual gridding structure imposed by the Border class can mostly be ignored. Realizing an under-all frame `self.window` already exists in the Dialogue class and making a few adjustments. Making a modal dialogue in Tkinter so only the top window is accessible for interaction. Changing the citation input in the source edit dialog to a Combobox. Starting on the work to get the source edit dialog to function as intended.
-
-
-
Adding a `UNIQUE` constraint to a SQLite database table column. Easy way to keep the database clean during testing so erroneous and incomplete data doesn't accumulate. Having a mysterious problem with getting text from the source input to fill in to the new source input in the edit source dialog.
-
-
-
Struggling to debug a mystifying problem up through about 14:00. The problem was caused by positional parameters being out of order. Rethinking code that was written blind without being able to test it. Working through the details of what should happen and when it should happen or not happen. To be continued.
-
-
-
Correcting SQL queries to get all the needed data out of the database. Tedious and long-winded debugging, continued in next video.
-
-
-
Moving some code that was being run at the wrong time. Lost in darkness. Video ended prematurely due to filmmaker error.
-
-
-
Joining two methods into one. Tracking code flow to scientifically learn what is going wrong, i.e. when certain things have to be done in a certain order at a certain time. Changing some local variables into instance variables since they're used after the `wait_window()` method when the dialog has been closed already. (After wait_window() runs, some local variables seem to have reverted to their default values.) Finally the new citation is successfully saved in the database. Getting a reference to the old citation ID in case the user presses CANCEL, so the table cell can be reset to its orginal value.
-
-
-
Explanation of how currently the source and citation are changed immediately when the source edit dialog opens but the citation ID in the database assertion table doesn't change till the dialog's OK button is pressed. But if the CANCEL button is pressed, the source and citation have to be reverted in the database to what they were before. Questioning the idea of putting the new source and citation into the database before the OK button has been pressed. More code being run in the wrong place has to be moved.
-
-
-
Moving some code that was running too early. Setting a boolean to be referenced later instead of running code too early. Reading the code carefully line by line to get everything happening at the right time. Adding more conditions to test so that all cases will be handled. Planning the next steps.
-
-
-
Giving values to a citations combobox for a source that already exists. Since this is the case where the source already exists, its citations are already stored in self.citation_values. Making a re-usable method for creating and renewing citation values for comboboxes.
-
-
-
Thinking about redrawing the whole assertions table when a change is made instead of picking away at updating this list and that dict etc. Dead air 5:08 - 5:54. Trying it the other way first, instead of just going back to the database and getting all the needed values and drawing a new assertions tab the same way the first one was made. The hesitation to doing it the redraw() way was based on the mistaken notion that a method inside of the AssertionsTab class would have to re-instantiate the AssertionsTab, and this was considered undesirable. The rest of this video is about trying unsuccessfully to not do it the easy way. Recovering Notepad++'s highlight matching brackets feature. Using Tkinter's `grid_slaves()` method to get a list of a widget's column-mates or row-mates.
-
-
-
Continuing down the wrong road instead of just redrawing the assertions tab when a change is made. No progress was made during this video.
-
-
-
Complaining that there are now two dictionaries using sources as the keys. Trying to save references to comboboxes in the same dictionary where sources are keys and citations are their correlated values. More convoluted effort upon effort to do it the hard way instead of just redrawing the assertions tab content the same way it was made the first time (by instantiating the class--the user can already redraw the assertions tab manually by re-clicking the SOURCES button to re-instantiate the class with the currently stored data).
-
-
-
I suggest skipping to ~14:45 where it finally becomes obvious that redrawing the assertions tab is the way to go when an edit is made in the tab. Looking at how the conclusions table is redrawn as a model. This odd procedure won't make a good model so instead we look close to home where the SOURCES button makes the assertions tab the first time, and then after making an edit to a cell in the assertions tab, pressing the SOURCES button again effortlessly redraws the assertions tab with its new content. The code run by the SOURCES button then is obviously the right code to model for redrawing the assertions tab programmatically after an edit is made to its content. Looking into whether the `open_assertions_dialog()` method can be imported or passed from findings_table.py. Determining whether assertions class has all the references needed to provide the arguments needed to run open_assertions_dialog() which up to now has only been run in findings_table.py. Passing the FindingsTable class to the AssertionsTab class in order to get access to one of its methods.
-
-
-
Removing code written while jousting at windmills before finally breaking down and doing it the easy/right way. Retesting the new ability to add a new source and citation and have the citation appear in relevant comboboxes immediately. Planning the next steps.
-
-
-
Introduction to the purpose of the source edit dialog. Changing the width of the combobox dropdown to approximate the width of the combobox entry. Updating some forgotten code from the repository dialog (got rid of error but stopped prematurely). Preparing the SQLite tool to be easily rolled back to its pristine condition numerous times as random changes are made while formatting the edit source dialog. Discussion of GUI design considerations regarding formatting decisions.
-
-
-
Gridding the widgets differently in the edit source dialog to make its purpose as obvious as possible. Adding some instructions in the dialog as a header. Changing the title in an instance of the Border class.
-
-
-
Looking at what additional functionalities should be included in the assertions feature. Thinking about where to put the inputs for new assertions and how to arrange them. Questioning the purpose and use of the event type column in the assertions tables. Correcting the dynamic display of text in the header of the assertion tab. Playing with combobox dropdown values.
-
-
-
Keeping track of which tab was active when the assertions tab is redrawn so the user can be returned to that tab. Looking at the TabBook class for the right attributes to use. Trying unsuccessfully to pass a method name to a different class from within the method itself.
-
-
-
Finding a usable model for a TabBook instance that can be used for an instance that replaces a prior instance. The goal here is to re-open the right tab in the assertions tab-book so the user doesn't get lost when the assertions tab gets redrawn. Getting a reference to the next widget in the tab traversal so it can be given focus dynamically when the correct tab is opened dynamically.
-
-
-
Why Treebard doesn't have an icon on the Windows taskbar when it's running, various ways to run it, and how to get its icon to show up on the taskbar when it's open (although the icon is not for Treebard but for the command prompt.) Making a new citation inside an existing source. Plan for the next series of videos. Cleaning junk out of the database that was added during tests. Getting little things done off the do list. Changing some column names in the database.
-
-
-
Giving default person #1 a default image and a default age of 0 at birth. Fixing some queries that should have been changed when the place feature was rewritten.
-
-
-
Showing how the database records a default age of zero and a default main image for the default person #1 who, along with his birth event, already exists in a new tree when it is created. Looking into why the accelerators don't work for the assertions tab-book (like ALT-P works to open the Person tab on the main tab-book). Dealing with a circular import.
-
-
-
Looking into adding statusbar tooltips and right-click context help menus. Discovering some needed changes to the roles dialog. Loud cricket singing directly into the microphone? Reorganizing the do list.
-
-
-
Review of Treebard's unique approach to conclusions, assertions, and evidence. Planning to add the last main subfeature of the assertions feature, which would be some widgets enabling the user to create new assertions, sources and citations. Adding a tab to the assertions tab-book. Getting a widget to display in the new tab. Going over the options of what sort of inputs should be in the add sources tab.
-
-
-
Changing label text conditionally. Making widgets for the add source tab. Changing the width of a Toykinter Combobox and its dropdown list. Using Tkinter's `sticky()` method to stretch an Entry widget into its available space.
-
-
-
Adding more widgets to the new source tab of the assertions tab-book. Making a button and callback to clear out all the inputs on the new source tab.
-
-
-
Setting the new source tab to open on load when the assertions tab-book is first displayed. Going over the plans and strategy for getting information out of the new dialog tab's widgets. Preventing an entry from accepting blank input.
-
-
-
Still planning to get current citations for combobox values when tabbing out of the source input. Trying to decide whether to copy code from another part of the class or write a custom method for this one combobox only. Database connections can't be passed to callbacks since you don't know when the function is going to be triggered by an event; the connection has to be made on demand by the callback itself.
-
-
-
Combobox dropdown values have extra verbiage not wanted in the database. Listing all the possible conditions and reconsidering each one of them. Decision that this has not been properly thought out in an orderly way.
-
-
-
Lecture to self about thinking things out in an orderly way. Listing all the things that can or must happen and keeping them straight in a flow chart showing necessary chains of logic. This long-winded process ultimately went nowhere because, before I got to the bottom of it, I realized I was trying to do too much in this feature anyway, and ended up removing some superfluous functionalities from the assertions tab which did not belong there.
-
-
-
At this point we have a brand new rake and we're using it to rake leaves in the middle of an autumn windstorm. It's finally realized that the fact that the edit source/citation dialog got opened can't have any logic based on it. With two values depending on each other and with getting the values being based on whether either of them changed, it's critical that final versions of both potentially changed values are gotten at the same time, upon the OK button's being pressed. It will eventually occur to me that trying to edit two co-dependent values on the fly like this is not worth the trouble and is just an edge case anyway in the context of the assertions tab.
-
-
-
It is finally realized that if source and citation depend on each other, their changing values should be tracked as two parts of a single variable. Maybe my first clue should have been: if a dialog is needed, too much has to be accomplished to try and do it on the fly. Figure out where the user would go to open a dialog to edit a source or add a citation with an OK button when done. Do it there, not while the user is visiting the assertions tables to review/add/edit assertions.
-
-
-
More of the same. I couldn't watch it to write a description, knowing that this code was all discarded in the morning.
-
-
-
Testing yesterday's code. @ 7:10 I finally see the light and begin to wonder why I'm trying to edit sources and citations--on the fly or any other way--in the assertions tab. There's a source tab, why not do that there, and write that code later on, when that feature's time to be born has come? After a fascinating discussion of my high school athletic prowess, the decision is made that revisions will ensue, mostly simplifications.
-
-
-
Preliminary plans to reduce the workload of the widgets in the assertions tab. Deleting irrelevant code and replacing EntryAuto widgets with Labels.
-
-
-
Adding instructions to the LabelHeader for editing an assertion. Getting an Entry and some Buttons to grid on top of the assertion Label if the Label is double-clicked. Adding commands to the Buttons. Trying to get the edit row frame to overlap other widgets by using the `place()` geometry manager instead of `grid()` or `pack()`. The problem was solved by gridding the edit row frame on top of the double-clicked Label instead of inside it.
-
-
-
Inserting the original Label text into the assertion editing input. Redesigning what's stored in the self.citations_by source dictionary. Within the database table `citation`, citations don't in general have to be unique, but within a given source (those citations linked to a certain source_id foreign key), the citations do have to be unique. Getting user input from the new source tab.
-
-
-
Writing methods to make a new event type or a new source if the user inputs an event type that doesn't exist yet or a source that doesn't exist yet.
-
-
-
Review of where we're currently at. Looking at what's been going into the database. Planning to add Radiobuttons so the user can indicate whether a new event type is a couple event or an after death event.
-
-
-
Adding text to Radiobuttons. Setting the default values on the Radiobuttons.
-
-
-
Ready to update database for new assertions, sources, and citations. Writing insert queries for the inputs in the new source tab.
-
-
-
Plans for testing the functionality for inputting new assertions, sources and citations. Plans for the next series of videos. What makes me think I've found the right Charles D. Gregory after searching for him for 12 years. Testing.
-
-
-
Testing the feature that unlinks an assertion from a finding and redraws the assertions table. Finding a reliable way to increment and decrement the text on the SOURCES button when an assertion is created or unlinked from the current finding.
-
-
-
Making sure the assertions already in the database are linked to the right finding. Using the GUI to unlink assertions from the wrong findings. Inputting a new conclusion. Inputting a span date. Getting rid of assertions that had been manually input redundantly. Setting surety where it should be on each assertion, using the GUI.
-
-
-
Inputting new assertions, sources and citations using the GUI.
-
-
-
Continuing to input new assertions to the family tree. Because of Treebard's assertions feature, you don't have to make two conclusions about the same thing to record conflicting data. The assertions feature also encourages the user to name his theory when using it as a source, making it convenient to keep track of theories and hunches--and their side effects--instead of having them float around wreaking havoc anonymously.
-
-
-
Finding ways to record more obscure or abstract assertions.
-
-
-
Why everyone should subscribe to the Treebard video channel. Going over the options of how to let the user know which tabs in the assertions tab-book have content so the user doesn't have to click on empty ones to find out if anything is in them. Wondering where to display assertions that aren't linked to a finding. Setting surety on assertions using the GUI. Writing a method in the TabBook class to add an asterisk to the tab text depending on the interests of the TabBook instance. Looking for an existing collection with a usable reference to the LabelTabs whose text needs to be reconfigured with an added "*".
-
-
-
Planning to add a tab to the assertions tab-book where unlinked assertions will be displayed. Getting the required information out of the database. Adding some columns to the assertions table in the UNLINKED tab.
-
-
-
Using the code from the `self.make_assertion_tables()` method differently in the UNLINKED tab. Structuring two collections the same so they can both be used by the same code.
-
-
-
Structuring two collections the same so they can both be used by the same code.
-
-
-
Replacing a list of tuples with a list of dictionaries. Looking at the unlinked assertions to decide what to do with each one. Writing a method to link an unlinked assertion to the current finding.
-
-
-
Groping in the dark till about 14:00. The problem was diluted by keeping the new method from impinging on the code that was already working. A pattern is detected in the bad behavior exhibited by the current state of the procedure.
-
-
-
Getting longer lines in the assertions table to wrap to a new line. Analyzing some troublesome code that had been copied without thinking about it. Solving a looping problem by starting a new loop instead of trying to do everything in one loop. Adding a button to the UNLINKED tab so unwanted assertions can be deleted completely. Formatting. Writing the code to delete assertions.
-
-
-
Adding a rudimentary functionality to the types tab, giving the user the ability to create his own event types as well as seeing what the event types are that already exist.
-
-
-
-
-
Summary of my experience with existing genealogy software, why I wanted to make my own genieware, and some of the goals of the Treebard project. Starting a new family tree from scratch. Off-topic demonstration of how databases are used without a graphical user interface (ends 17:00). How events are sorted in the conclusions table. Changing the name of default person #1. Names are one string, Treebard doesn't use the first/middle/last naming convention since it's not applicable to many different cultures. Off-topic code fix 23:10-30:35. Challenges of researching the current family.
-
-
-
How I ended up creating family trees for old-time inventors. Different ways to open an existing tree. Starting off with a census page. Trying to use the date calculator in another genieware. Date input in Treebard. Difference between 'about' dates and 'estimated' dates. Setting preferences on date display. Changing current person by autofilling the name of an existing person or inputting the person's ID if you know it. Inputting conclusions about dates and places to existing events in the conclusions table. Inputting assertions, sources, and citations to show what conclusions were based on. Distinction between conclusions, assertions, finding, sources, and citations. Veracity of peoples' ages in genealogy documents. Assertion is exactly what a source says, without paraphrasing or interpretation. Inputting a new place. Editing surety on the assertions table.
-
-
-
Feature needed for adding source, citations and assertions without having to link them to elements in the conclusions table at the same time. Distinction between event, attribute, conclusion, finding, and assertion. Adding parents and siblings to an existing person. Adding a spouse to the current person. Adding a sibling and editing their birth or death date. How to report a bug (what happened, when did it happen, entire error message). "1929" should be "1919" for the 11-year-old in 1930. Adding an age assertion from the census. Adding a finding to the conclusions table by selecting a new event type. Treebard never uses numbers for months but otherwise, date input is very free. When autofilling an existing place into a place field, it's not necessary to capitalize the place name. Sources autofill into source fields when you start typing. Existing citations can be selected from a combobox instead of copy-pasting them over and over.
-
-
-
Introduction to the added features since the last video in this series was made. Setting the default directory for image source in Preferences > Where. To link multiple images at the same time to the current person, add the images while adding the person. Adding images to the tree without linking them to an element. Linking images to a person. Making one image the main image for the current element by linking it first. Using Treebard's graphics tab to create a resized copy of an image. Deleting an image from the tree. Resizing images that are already in the tree. Deleting oversized originals from the tree and linking the resized copies to the current person. Linking the same image to multiple elements e.g. two different people.
-
-
-
Trying to input an image caption to the database. Changing an existing name and name type at the same time. Editing an existing date on the conclusions table. Linking a document image to a source. Plans to add a feature for adding and editing citations and sources without linking them to a finding. Pondering the research already collected for features that need to be added before the next video is made. Adding do list items.
-
-