- A Logbook now contains Log objects that contain the Records. These Log objects are displayed as tabs in a Gtk.Notebook.

- Added the option to close a particular log.
- Added toolbar buttons for creating/opening/saving/closing logs.
- More error checking.
- The pyqso.py file is now much shorter, as most of the code has been moved to logbook.py or log.py.
pull/17/head
Christian Jacobs 2013-03-27 20:29:43 +00:00
rodzic 479e3a4d32
commit e3186585c0
7 zmienionych plików z 294 dodań i 140 usunięć

112
src/log.py 100644
Wyświetl plik

@ -0,0 +1,112 @@
#!/usr/bin/env python
# File: log.py
# Copyright (C) 2013 Christian Jacobs.
# This file is part of PyQSO.
# PyQSO is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyQSO is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PyQSO. If not, see <http://www.gnu.org/licenses/>.
from gi.repository import Gtk, GObject
import logging
from adif import AVAILABLE_FIELD_NAMES_TYPES
from record import *
from record_dialog import *
class Log(Gtk.ListStore):
''' A Log object can store multiple Record objects. '''
def __init__(self, records=None, name="Untitled"):
# FIXME: Allow the user to select the field names. By default, let's select them all.
self.SELECTED_FIELD_NAMES_TYPES = AVAILABLE_FIELD_NAMES_TYPES
self.SELECTED_FIELD_NAMES_ORDERED = ["CALL", "DATE", "TIME", "FREQ", "BAND", "MODE", "RST_SENT", "RST_RCVD"]
self.SELECTED_FIELD_NAMES_FRIENDLY = {"CALL":"Callsign",
"DATE":"Date",
"TIME":"Time",
"FREQ":"Frequency",
"BAND":"Band",
"MODE":"Mode",
"RST_SENT":"TX RST",
"RST_RCVD":"RX RST"}
# The ListStore constructor needs to know the data types of the columns.
# The index is always an integer. We will assume the ADIF fields are strings.
data_types = [int] + [str]*len(self.SELECTED_FIELD_NAMES_ORDERED)
# Call the constructor of the super class (Gtk.ListStore)
Gtk.ListStore.__init__(self, *data_types)
self.name = name
if(records is None):
# Begin with no records.
self.records = []
else:
self.records = records
# Populate the ListStore with Record-containing rows
self.populate()
logging.debug("New Log instance created!")
def check_consistency(self):
# Make sure all the record indices are consecutive and
# correctly ordered.
for i in range(0, len(self.records)):
if(self[i][0] != i):
self[i][0] = i
return
def populate(self):
# Remove everything that is rendered already and start afresh
self.clear()
for i in range(0, len(self.records)):
log_entry = [] # Create a new log entry
# First append the unique index given to the record.
log_entry.append(i)
for field in self.SELECTED_FIELD_NAMES_ORDERED:
log_entry.append(self.records[i].get_data(field))
self.append(log_entry)
return
def add_record(self, fields_and_data):
record = Record(fields_and_data)
self.records.append(record)
# Hopefully this won't change anything as check_consistency
# is also called in delete_record, but let's keep it
# here as a sanity check.
self.check_consistency()
return
def delete_record(self, index, iter):
# Get the selected row in the logbook
self.records.pop(index)
self.remove(iter)
self.check_consistency()
return
def edit_record(self, index, field_name, data):
self.records[index].set_data(field_name, data)
return
def get_record(self, index):
return self.records[index]
def get_number_of_records(self):
return len(self.records)

Wyświetl plik

@ -22,44 +22,31 @@ from gi.repository import Gtk, GObject
import logging
from adif import *
from record import *
from record_dialog import *
from log import *
class Logbook(Gtk.ListStore):
class Logbook(Gtk.Notebook):
''' A Logbook object can store multiple Log objects. '''
def __init__(self):
# FIXME: Allow the user to select the field names. By default, let's select them all.
self.SELECTED_FIELD_NAMES_TYPES = AVAILABLE_FIELD_NAMES_TYPES
self.SELECTED_FIELD_NAMES_ORDERED = ["CALL", "DATE", "TIME", "FREQ", "BAND", "MODE", "RST_SENT", "RST_RCVD"]
self.SELECTED_FIELD_NAMES_FRIENDLY = {"CALL":"Callsign",
"DATE":"Date",
"TIME":"Time",
"FREQ":"Frequency",
"BAND":"Band",
"MODE":"Mode",
"RST_SENT":"TX RST",
"RST_RCVD":"RX RST"}
# The ListStore constructor needs to know the data types of the columns.
# The index is always an integer. We will assume the ADIF fields are strings.
data_types = [int] + [str]*len(self.SELECTED_FIELD_NAMES_ORDERED)
# Call the constructor of the super class (Gtk.ListStore)
Gtk.ListStore.__init__(self, *data_types)
# Begin with no records.
self.records = []
Gtk.Notebook.__init__(self)
# A stack of Log objects
self.logs = []
# For rendering the logs. One treeview and one treeselection per Log.
self.treeview = []
self.treeselection = []
logging.debug("New Logbook instance created!")
def new_log(self, widget):
self.records = []
self.populate()
def new_log(self, widget=None):
l = Log() # Empty log
self.logs.append(l)
self.render_log(l)
return
def open_log(self, widget):
def open_log(self, widget=None):
dialog = Gtk.FileChooserDialog("Open File",
None,
Gtk.FileChooserAction.OPEN,
@ -82,12 +69,20 @@ class Logbook(Gtk.ListStore):
return
adif = ADIF()
self.records = adif.read(path)
self.populate()
records = adif.read(path)
l = Log(records, path)
self.logs.append(l)
self.render_log(l)
return
def save_log(self, widget):
def save_log(self, widget=None):
current = self.get_current_page() # Gets the index of the selected tab in the logbook
if(current == -1):
logging.debug("No log files to save!")
return
dialog = Gtk.FileChooserDialog("Save File",
None,
Gtk.FileChooserAction.SAVE,
@ -105,14 +100,72 @@ class Logbook(Gtk.ListStore):
logging.debug("No file path specified.")
return
log = self.logs[current]
adif = ADIF()
adif.write(self.records, path)
adif.write(log.records, path)
#current.set_tab_label(path)
return
def close_log(self, widget=None):
current = self.get_current_page() # Gets the index of the selected tab in the logbook
if(current == -1):
logging.debug("No log files to close!")
return
self.logs.pop(current)
# Remove the log from the renderers too
self.treeview.pop(current)
self.treeselection.pop(current)
# And finally remove the tab in the Logbook
self.remove_page(current)
return
def render_log(self, log):
# Render the Log
current = self.get_number_of_logs()-1
self.treeview.append(Gtk.TreeView(log))
self.treeview[current].set_grid_lines(Gtk.TreeViewGridLines.BOTH)
self.treeview[current].connect("row-activated", self.edit_record_callback, self)
self.treeselection.append(self.treeview[current].get_selection())
self.treeselection[current].set_mode(Gtk.SelectionMode.SINGLE)
# Allow the Log to be scrolled up/down
sw = Gtk.ScrolledWindow()
sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
sw.add(self.treeview[current])
vbox = Gtk.VBox()
vbox.pack_start(sw, True, True, 0)
self.append_page(vbox, Gtk.Label(self.logs[current].name)) # Append the new log as a new tab
# The first column of the logbook will always be the unique record index.
# Let's append this separately to the field names.
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Index", renderer, text=0)
column.set_resizable(True)
column.set_min_width(50)
self.treeview[current].append_column(column)
# Set up column names for each selected field
field_names = self.logs[current].SELECTED_FIELD_NAMES_ORDERED
for i in range(0, len(field_names)):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(self.logs[current].SELECTED_FIELD_NAMES_FRIENDLY[field_names[i]], renderer, text=i+1)
column.set_resizable(True)
column.set_min_width(50)
self.treeview[current].append_column(column)
self.show_all()
def add_record_callback(self, widget, parent):
dialog = RecordDialog(parent, index=None)
current = self.get_current_page() # Gets the index of the selected tab in the logbook
if(current == -1):
logging.debug("Tried to add a record, but no log present!")
return
log = self.logs[current]
dialog = RecordDialog(root_window=parent, log=log, index=None)
all_valid = False # Are all the field entries valid?
while(not all_valid):
@ -123,7 +176,7 @@ class Logbook(Gtk.ListStore):
response = dialog.run() #FIXME: Is it ok to call .run() multiple times on the same RecordDialog object?
if(response == Gtk.ResponseType.OK):
fields_and_data = {}
field_names = self.SELECTED_FIELD_NAMES_ORDERED
field_names = log.SELECTED_FIELD_NAMES_ORDERED
for i in range(0, len(field_names)):
#TODO: Validate user input!
fields_and_data[field_names[i]] = dialog.get_data(field_names[i])
@ -139,28 +192,24 @@ class Logbook(Gtk.ListStore):
if(all_valid):
# All data has been validated, so we can go ahead and add the new record.
logbook_entry = [len(self.records)] # Add the next available record index
field_names = self.SELECTED_FIELD_NAMES_ORDERED
log_entry = [log.get_number_of_records()] # Add the next available record index
field_names = log.SELECTED_FIELD_NAMES_ORDERED
for i in range(0, len(field_names)):
logbook_entry.append(fields_and_data[field_names[i]])
self.append(logbook_entry)
record = Record(fields_and_data)
self.records.append(record)
# Hopefully this won't change anything as check_consistency
# is also called in delete_record, but let's keep it
# here as a sanity check.
self.check_consistency()
log_entry.append(fields_and_data[field_names[i]])
log.append(log_entry)
log.add_record(fields_and_data)
# Select the new Record's row in the treeview.
parent.treeselection.select_path(self.get_number_of_records()-1)
self.treeselection[current].select_path(log.get_number_of_records()-1)
dialog.destroy()
return
def delete_record_callback(self, widget, parent):
# Get the selected row in the logbook
(model, path) = parent.treeselection.get_selected_rows()
current = self.get_current_page() # Get the selected log
if(current == -1):
logging.debug("Tried to delete a record, but no log present!")
return
(model, path) = self.treeselection[current].get_selected_rows() # Get the selected row in the log
try:
iter = model.get_iter(path[0])
index = model.get_value(iter,0)
@ -173,11 +222,9 @@ class Logbook(Gtk.ListStore):
"Are you sure you want to delete record %d?" % index)
response = dialog.run()
if(response == Gtk.ResponseType.YES):
# Deletes the record with index 'index' from self.records.
# Deletes the record with index 'index' from the Records list.
# 'iter' is needed to remove the record from the ListStore itself.
self.records.pop(index)
self.remove(iter)
self.check_consistency()
self.logs[current].delete_record(index, iter)
dialog.destroy()
@ -187,8 +234,11 @@ class Logbook(Gtk.ListStore):
# Note: the path and view_column arguments need to be passed in
# since they associated with the row-activated signal.
# Get the selected row in the logbook
(model, path) = parent.treeselection.get_selected_rows()
current = self.get_current_page() # Get the selected log
if(current == -1):
logging.debug("Tried to edit a record, but no log present!")
return
(model, path) = self.treeselection[current].get_selected_rows() # Get the selected row in the log
try:
iter = model.get_iter(path[0])
row_index = model.get_value(iter,0)
@ -196,7 +246,7 @@ class Logbook(Gtk.ListStore):
logging.debug("Could not find the selected row's index!")
return
dialog = RecordDialog(parent, index=row_index)
dialog = RecordDialog(root_window=parent, log=self.logs[current], index=row_index)
all_valid = False # Are all the field entries valid?
while(not all_valid):
@ -207,7 +257,7 @@ class Logbook(Gtk.ListStore):
response = dialog.run() #FIXME: Is it ok to call .run() multiple times on the same RecordDialog object?
if(response == Gtk.ResponseType.OK):
fields_and_data = {}
field_names = self.SELECTED_FIELD_NAMES_ORDERED
field_names = self.logs[current].SELECTED_FIELD_NAMES_ORDERED
for i in range(0, len(field_names)):
#TODO: Validate user input!
fields_and_data[field_names[i]] = dialog.get_data(field_names[i])
@ -225,40 +275,16 @@ class Logbook(Gtk.ListStore):
for i in range(0, len(field_names)):
# All data has been validated, so we can go ahead and update the record.
# First update the Record object...
self.records[row_index].set_data(field_names[i], fields_and_data[field_names[i]])
log = self.logs[current]
log.edit_record(row_index, field_names[i], fields_and_data[field_names[i]])
# ...and then the Logbook.
# (we add 1 onto the column_index here because we don't want to consider the index column)
self[row_index][i+1] = fields_and_data[field_names[i]]
log[row_index][i+1] = fields_and_data[field_names[i]]
dialog.destroy()
return
def get_number_of_records(self):
return len(self.records)
def get_number_of_logs(self):
return len(self.logs)
def get_record(self, index):
return self.records[index]
def check_consistency(self):
# Make sure all the record indices are consecutive and
# correctly ordered.
for i in range(0, len(self.records)):
if(self[i][0] != i):
self[i][0] = i
return
def populate(self):
# Remove everything that is rendered already and start afresh
self.clear()
for i in range(0, len(self.records)):
logbook_entry = [] # Create a new logbook entry
# First append the unique index given to the record.
logbook_entry.append(i)
for field in self.SELECTED_FIELD_NAMES_ORDERED:
logbook_entry.append(self.records[i].get_data(field))
self.append(logbook_entry)
return

Wyświetl plik

@ -23,13 +23,11 @@ import logging
class Menu(Gtk.MenuBar):
def __init__(self, parent, vbox):
def __init__(self, parent):
logging.debug("New Menu instance created!")
# First let's call the constructor of the super class (Gtk.MenuBar)
Gtk.MenuBar.__init__(self)
vbox.pack_start(self, False, False, 0)
agrp = Gtk.AccelGroup()
parent.add_accel_group(agrp)
@ -60,6 +58,12 @@ class Menu(Gtk.MenuBar):
key, mod = Gtk.accelerator_parse("<Control>S")
mitem_save.add_accelerator("activate", agrp, key, mod, Gtk.AccelFlags.VISIBLE)
subm_file.append(mitem_save)
# Close the current log
mitem_close = Gtk.MenuItem("Close Log")
mitem_close.connect("activate", parent.logbook.close_log)
mitem_close.add_accelerator("activate", agrp, key, mod, Gtk.AccelFlags.VISIBLE)
subm_file.append(mitem_close)
subm_file.append(Gtk.SeparatorMenuItem())

Wyświetl plik

@ -46,41 +46,18 @@ class PyQSO(Gtk.Window):
# Create a Logbook so we can add/remove/edit Record objects
self.logbook = Logbook()
self.logbook.new_log() # Create a new log by default.
# Set up menu and tool bars
menu = Menu(self, vbox_outer)
toolbar = Toolbar(self, vbox_outer)
# Render the logbook
self.treeview = Gtk.TreeView(self.logbook)
self.treeview.set_grid_lines(Gtk.TreeViewGridLines.BOTH)
self.treeview.connect("row-activated", self.logbook.edit_record_callback, self)
self.treeselection = self.treeview.get_selection()
self.treeselection.set_mode(Gtk.SelectionMode.SINGLE)
# Allow the Logbook to be scrolled up/down
sw = Gtk.ScrolledWindow()
sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
sw.add(self.treeview)
vbox_outer.pack_start(sw, True, True, 0)
# The first column of the logbook will always be the unique record index.
# Let's append this separately to the field names.
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Index", renderer, text=0)
column.set_resizable(True)
column.set_min_width(50)
self.treeview.append_column(column)
# Set up column names for each selected field
field_names = self.logbook.SELECTED_FIELD_NAMES_ORDERED
for i in range(0, len(field_names)):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(self.logbook.SELECTED_FIELD_NAMES_FRIENDLY[field_names[i]], renderer, text=i+1)
column.set_resizable(True)
column.set_min_width(50)
self.treeview.append_column(column)
# These classes depend on the Logbook class,
# so pack the logbook after the menu and toolbar.
menu = Menu(self)
vbox_outer.pack_start(menu, False, False, 0)
toolbar = Toolbar(self)
vbox_outer.pack_start(toolbar, False, False, 0)
vbox_outer.pack_start(self.logbook, True, True, 0)
self.statusbar = Gtk.Statusbar()
context_id = self.statusbar.get_context_id("Status")
vbox_outer.pack_start(self.statusbar, False, False, 0)

Wyświetl plik

@ -34,7 +34,7 @@ class Record:
except KeyError:
# If we can't find the field name, return None
logging.warning("Field name %s not found in the record!" % field_name)
data = None
data = ""
return data
def set_data(self, field_name, data):

Wyświetl plik

@ -21,19 +21,18 @@
from gi.repository import Gtk, GObject
import logging
from adif import AVAILABLE_FIELD_NAMES_TYPES
from callsign_lookup import *
class RecordDialog(Gtk.Dialog):
def __init__(self, parent, index=None):
def __init__(self, root_window, log, index=None):
logging.debug("New RecordDialog instance created!")
if(index is not None):
title = "Edit Record %d" % index
else:
title = "Add Record"
Gtk.Dialog.__init__(self, title=title, parent=parent, flags=Gtk.DialogFlags.DESTROY_WITH_PARENT, buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK))
Gtk.Dialog.__init__(self, title=title, parent=root_window, flags=Gtk.DialogFlags.DESTROY_WITH_PARENT, buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK))
frame = Gtk.Frame()
label = Gtk.Label("QSO Data")
@ -46,7 +45,7 @@ class RecordDialog(Gtk.Dialog):
# CALL
hbox_temp = Gtk.HBox(spacing=0)
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["CALL"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["CALL"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
self.sources["CALL"] = Gtk.Entry()
@ -58,14 +57,14 @@ class RecordDialog(Gtk.Dialog):
# DATE
hbox_temp = Gtk.HBox(spacing=0)
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["DATE"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["DATE"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
self.sources["DATE"] = Gtk.Entry()
hbox_temp.pack_start(self.sources["DATE"], True, True, 6)
# TIME
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["TIME"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["TIME"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
self.sources["TIME"] = Gtk.Entry()
@ -74,14 +73,14 @@ class RecordDialog(Gtk.Dialog):
# FREQ
hbox_temp = Gtk.HBox(spacing=0)
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["FREQ"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["FREQ"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
self.sources["FREQ"] = Gtk.Entry()
hbox_temp.pack_start(self.sources["FREQ"], True, True, 6)
# BAND
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["BAND"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["BAND"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
bands = ["", "2190m", "560m", "160m", "80m", "60m", "40m", "30m", "20m", "17m", "15m", "12m", "10m", "6m", "4m", "2m", "1.25m", "70cm", "33cm", "23cm", "13cm", "9cm", "6cm", "3cm", "1.25cm", "6mm", "4mm", "2.5mm", "2mm", "1mm"]
@ -94,7 +93,7 @@ class RecordDialog(Gtk.Dialog):
# MODE
hbox_temp = Gtk.HBox(spacing=0)
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["MODE"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["MODE"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
modes = ["", "AM", "AMTORFEC", "ASCI", "ATV", "CHIP64", "CHIP128", "CLO", "CONTESTI", "CW", "DSTAR", "DOMINO", "DOMINOF", "FAX", "FM", "FMHELL", "FSK31", "FSK441", "GTOR", "HELL", "HELL80", "HFSK", "ISCAT", "JT44", "JT4A", "JT4B", "JT4C", "JT4D", "JT4E", "JT4F", "JT4G", "JT65", "JT65A", "JT65B", "JT65C", "JT6M", "MFSK8", "MFSK16", "MT63", "OLIVIA", "PAC", "PAC2", "PAC3", "PAX", "PAX2", "PCW", "PKT", "PSK10", "PSK31", "PSK63", "PSK63F", "PSK125", "PSKAM10", "PSKAM31", "PSKAM50", "PSKFEC31", "PSKHELL", "Q15", "QPSK31", "QPSK63", "QPSK125", "ROS", "RTTY", "RTTYM", "SSB", "SSTV", "THRB", "THOR", "THRBX", "TOR", "V4", "VOI", "WINMOR", "WSPR"]
@ -107,14 +106,14 @@ class RecordDialog(Gtk.Dialog):
# RST_SENT
hbox_temp = Gtk.HBox(spacing=0)
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["RST_SENT"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["RST_SENT"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
self.sources["RST_SENT"] = Gtk.Entry()
hbox_temp.pack_start(self.sources["RST_SENT"], True, True, 6)
# RST_RCVD
label = Gtk.Label(parent.logbook.SELECTED_FIELD_NAMES_FRIENDLY["RST_RCVD"])
label = Gtk.Label(log.SELECTED_FIELD_NAMES_FRIENDLY["RST_RCVD"])
label.set_alignment(0, 0.5)
hbox_temp.pack_start(label, False, False, 6)
self.sources["RST_RCVD"] = Gtk.Entry()
@ -123,8 +122,8 @@ class RecordDialog(Gtk.Dialog):
if(index is not None):
# The record already exists, so display its current data in the input boxes.
record = parent.logbook.get_record(index)
field_names = parent.logbook.SELECTED_FIELD_NAMES_ORDERED
record = log.get_record(index)
field_names = log.SELECTED_FIELD_NAMES_ORDERED
for i in range(0, len(field_names)):
if(field_names[i] == "BAND"):
self.sources[field_names[i]].set_active(bands.index(record.get_data(field_names[i])))

Wyświetl plik

@ -23,11 +23,49 @@ import logging
class Toolbar(Gtk.HBox):
def __init__(self, parent, vbox_parent):
def __init__(self, parent):
logging.debug("New Toolbar instance created!")
Gtk.HBox.__init__(self, spacing=2)
# New log
icon = Gtk.Image()
icon.set_from_stock(Gtk.STOCK_NEW, Gtk.IconSize.BUTTON)
button = Gtk.Button()
button.add(icon)
button.set_tooltip_text('New log')
button.connect("clicked", parent.logbook.new_log)
self.pack_start(button, False, False, 0)
# Open log
icon = Gtk.Image()
icon.set_from_stock(Gtk.STOCK_OPEN, Gtk.IconSize.BUTTON)
button = Gtk.Button()
button.add(icon)
button.set_tooltip_text('Open log')
button.connect("clicked", parent.logbook.open_log)
self.pack_start(button, False, False, 0)
# Save log
icon = Gtk.Image()
icon.set_from_stock(Gtk.STOCK_SAVE, Gtk.IconSize.BUTTON)
button = Gtk.Button()
button.add(icon)
button.set_tooltip_text('Save log')
button.connect("clicked", parent.logbook.save_log)
self.pack_start(button, False, False, 0)
# Close log
icon = Gtk.Image()
icon.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.BUTTON)
button = Gtk.Button()
button.add(icon)
button.set_tooltip_text('Close log')
button.connect("clicked", parent.logbook.close_log)
self.pack_start(button, False, False, 0)
self.pack_start(Gtk.SeparatorMenuItem(), False, False, 0)
# Add record
icon = Gtk.Image()
icon.set_from_stock(Gtk.STOCK_ADD, Gtk.IconSize.BUTTON)
@ -55,6 +93,4 @@ class Toolbar(Gtk.HBox):
button.connect("clicked", parent.logbook.delete_record_callback, parent)
self.pack_start(button, False, False, 0)
vbox_parent.pack_start(self, False, False, 0)
return