cgiannakidis
cgiannakidis

Reputation: 91

how to store in a list or dictionary the date from Gtk.Calendar.get_date() and a text from Gtk.TextBuffer for that date in python

I am trying to create a calendar app in python.As for now I have manage to create the Gtk.window, a Gtk.Notebook with two pages (page1 month calendar, page 2 week calendar) added to the Gtk.window.I have used Gtk.Calendar for month and from signal 'day-selected' I used a function to get_date().Also I used a Gtk.TextView with Gtk.TextBuffer to input text (as a note).

First question : how to connect the date with the input text and store it in a list or dictionary so i can save it later to a file.

Second:I have activate details with self.calendar.set_property("show-details", True) and defined a function self.calendar.set_detail_func(self.cal_entry) for details.

    def cal_entry(self, calendar, year, month, date):
        if self.textbuffer is not None:

           self.calendar.mark_day(self.day)

How to mark the days with notes(text in Gtk.TextBuffer) because the above function does not work correctly.

Below is a snippet of the code:

class Window(Gtk.ApplicationWindow):

    def __init__(self, app):
        super(Window, self).__init__(title="Live Calendar", application=app)
        self.set_default_size(-1, 400)
        self.set_resizable(False)
        self.set_border_width(10)
        self.create_notebook()
        self.entry()
        self.refresh_icon()

    def refresh_icon(self):
        #refreshing the icon of the app 
        print(get_filename())
        subject_lines = read_file(subject)
        index = [i for i in range(len(subject_lines)) \
                 if subject_lines[i].startswith("Icon=")][0]
        subject_lines[index] = "Icon=" + get_filename() + "\n"
        write_file(subject, subject_lines)
        self.set_icon_from_file(get_filename())
        timer = threading.Timer(60, self.refresh_icon)
        timer.start()

    def create_notebook(self):
        # Open Buttton
        self.openbutton = Gtk.Button("Open")
        self.openbutton.set_tooltip_text("Open Notes")
        self.openbutton.connect("clicked", self.on_open_clicked)

        # Save Button
        self.savebutton = Gtk.Button("Save")
        self.savebutton.set_tooltip_text("Save Notes")
        self.savebutton.connect("clicked", self.on_save_clicked)

        # Header
        self.header = Gtk.HeaderBar(title="Live Calendar")
        self.header.set_property("show_close_button", True)
        self.header.pack_start(self.openbutton)
        self.header.pack_start(self.savebutton)
        self.set_titlebar(self.header)

        #page1 month calendar
        self.page1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        self.calendar = Gtk.Calendar()
        self.calendar.set_property("show-week-numbers", True)
        self.calendar.set_detail_height_rows(2)
        self.calendar.set_detail_width_chars(2)
        self.calendar.set_property("show-details", True)
        self.calendar.set_detail_func(self.cal_entry)
        self.__connect_signals()
        self.page1.add(self.calendar)

        #note taking
        self.sw = Gtk.ScrolledWindow()
        self.sw.set_hexpand(True)
        self.sw.set_vexpand(True)
        self.textview = Gtk.TextView()
        self.textview.set_editable(True)
        self.textview.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
        self.textbuffer = self.textview.get_buffer()

        self.sw.add(self.textview)
        self.page1.pack_start(self.sw, True, True, 0)

        #page2 week calendar




        ......a lot of code.......





        #create notebook
        self.notebook = Gtk.Notebook()
        self.notebook.set_tab_pos(0)
        self.notebook.append_page(self.page1, Gtk.Label('Month'))
        self.notebook.append_page(self.page2, Gtk.Label('Week'))

        self.add(self.notebook)

    def __connect_signals(self):
        self.day_selected_handle = self.calendar.connect('day-selected', self.entry)

    def entry(self, *args):
        self.page1.remove(self.label)
        self.year, self.month, self.day = self.calendar.get_date()
        self.month = self.month + 1
        self.entrydate = datetime.date(self.year, self.month, self.day)
        self.notedate = self.entrydate.strftime("%d/%m/%y")

        self.text = self.entrydate.strftime("%d/%m/%y  write your notes here...")
        self.label = Gtk.Label(self.text)
        self.page1.pack_start(self.label, False, False, 0)
        self.show_all()


    def cal_entry(self, calendar, year, month, date):
        if self.textbuffer is not None:

            self.calendar.mark_day(self.day)

    #save into file 
    def on_save_clicked(self, widget):
        dialog = Gtk.FileChooserDialog("Save file", self,
                                       Gtk.FileChooserAction.SAVE,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_SAVE, Gtk.ResponseType.OK))

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            save_file = dialog.get_filename()
            start_iter = self.textbuffer.get_start_iter()
            end_iter = self.textbuffer.get_end_iter()
            text = self.textbuffer.get_text(start_iter, end_iter, True)
            with open(save_file, 'w') as f:
                f.write(text)
        elif response == Gtk.ResponseType.CANCEL:
            dialog.destroy()

        dialog.destroy()

    # open and read the file
    def on_open_clicked(self, widget):
        dialog = Gtk.FileChooserDialog("Please choose a file", self,
                                       Gtk.FileChooserAction.OPEN,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))

        filter_text = Gtk.FileFilter()
        filter_text.set_name("Text files")
        filter_text.add_mime_type("text/plain")
        dialog.add_filter(filter_text)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            selected_file = dialog.get_filename()
            with open(selected_file, 'r') as f:
                data = f.read()
                self.textbuffer.set_text(data)
        elif response == Gtk.ResponseType.CANCEL:
            dialog.destroy()

        dialog.destroy()

    def quitApp(self, par):
        app.quit()


class Application(Gtk.Application):

    def __init__(self):
        super(Application, self).__init__()

    def do_activate(self):
        self.win = Window(self)
        self.win.show_all()

    def do_startup(self):
        Gtk.Application.do_startup(self)


app = Application()
app.run(sys.argv)

Any help will be appriciated.

Thanks in advance

Upvotes: 1

Views: 437

Answers (1)

lb90
lb90

Reputation: 958

For the first question: Depends, but probably a dictionary indexed by a triple for y/m/d

d = dict()
d[(2019, 10, 1)] = "your notes..."

Second question: The way details work is that cal_entry(self, calendar, year, month, day) must return a string to be displayed below the day, in the calendar. So you have to get the text from the dictionary above. You can do that with:

def cal_entry(self, calendar, year, month, day):
  self.calendar.mark_day(day)
  return dict.get((year, month, day))

Maybe this sample code can help:

#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class NotePopover(Gtk.Popover):
  def __init__(self, app):
    Gtk.Popover.__init__(self)

    self.set_size_request(200, 300)

    grid = Gtk.Grid()
    grid.set_orientation(Gtk.Orientation.VERTICAL)
    scrolled_window = Gtk.ScrolledWindow()
    self.text_view = Gtk.TextView()
    scrolled_window.add(self.text_view)
    grid.add(scrolled_window)
    button = Gtk.Button(label='Add')
    grid.add(button)
    grid.show_all()
    self.add(grid)

    scrolled_window.set_vexpand(True)
    scrolled_window.set_hexpand(True)

    button.connect('clicked', self.on_button_clicked)

    self.app = app

  def do_popup(self):
    self.popup()

  def on_button_clicked(self, widget):
    year = app.win.calendar.get_property('year')
    month = app.win.calendar.get_property('month')
    day = app.win.calendar.get_property('day')

    start_iter = self.text_view.get_buffer().get_start_iter()
    end_iter = self.text_view.get_buffer().get_end_iter()
    app.notes_dict[(year, month, day)] = self.text_view.get_buffer().get_text(start_iter, end_iter, True)

    app.win.do_update()

    self.text_view.get_buffer().set_text("")
    self.popdown()

class Window(Gtk.Window):
  def __init__(self, app):
    Gtk.Window.__init__(self)
    self.set_title('Test GtkCalendar')
    self.set_default_size(400, 300)

    header_bar = Gtk.HeaderBar()
    header_bar.set_show_close_button(True)
    self.set_titlebar(header_bar)

    button = Gtk.Button(label="Add note")
    button.get_style_context().add_class('suggested-action')
    button.connect('clicked', self.on_button_clicked)
    header_bar.pack_start(button)

    grid = Gtk.Grid()
    grid.set_orientation(Gtk.Orientation.VERTICAL)
    self.calendar = Gtk.Calendar()
    scrolled_window = Gtk.ScrolledWindow()
    self.text_view = Gtk.TextView()

    self.add(grid)
    grid.add(self.calendar)
    grid.add(scrolled_window)
    scrolled_window.add(self.text_view)

    self.calendar.set_hexpand(True)
    self.calendar.set_halign(Gtk.Align.CENTER)
    scrolled_window.set_vexpand(True)
    scrolled_window.set_hexpand(True)

    self.popover = NotePopover(app)
    self.popover.set_relative_to(button)

    self.connect('destroy', Gtk.main_quit)
    self.calendar.connect('day-selected', self.calendar_changed)
    self.calendar.connect('month-changed', self.calendar_changed)

    self.show_all()

    self.app = app

  def on_button_clicked(self, widget):
    self.popover.do_popup()

  def calendar_changed(self, widget):
    self.do_update()

  def do_update(self):
    year = app.win.calendar.get_property('year')
    month = app.win.calendar.get_property('month')
    day = app.win.calendar.get_property('day')

    text = app.notes_dict.get((year, month, day))

    if text is not None:
        self.text_view.get_buffer().set_text(text)
    else:
        self.text_view.get_buffer().set_text("")

class Application:
  def __init__(self):
    self.notes_dict = dict()
    self.win = Window(self)

if __name__ == '__main__':
  app = Application()
  Gtk.main()

Upvotes: 2

Related Questions