18
18
# indicator-stickynotes. If not, see <http://www.gnu.org/licenses/>.
20
20
from stickynotes.backend import Note, NoteSet
21
from stickynotes.gui import *
22
import stickynotes.info
23
from stickynotes.info import MO_DIR, LOCALE_DOMAIN
21
from stickynotes.gui import StickyNote
25
22
from gi.repository import Gtk, Gdk
26
23
from gi.repository import AppIndicator3 as appindicator
31
from locale import gettext as _
32
from functools import wraps
33
from shutil import copyfile, SameFileError
36
"""Wrapper for functions that require a save after execution"""
38
def _wrapper(self, *args, **kwargs):
39
ret = f(self, *args, **kwargs)
44
25
class IndicatorStickyNotes:
45
def __init__(self, args = None):
47
# use development data file if requested
48
isdev = args and args.d
49
self.data_file = stickynotes.info.DEBUG_SETTINGS_FILE if isdev \
50
else stickynotes.info.SETTINGS_FILE
51
27
# Initialize NoteSet
52
self.nset = NoteSet(StickyNote, self.data_file, self)
55
except FileNotFoundError:
56
self.nset.load_fresh()
57
except Exception as e:
58
err = _("Error reading data file. Do you want to "
59
"backup the current data?")
60
winError = Gtk.MessageDialog(None, None, Gtk.MessageType.ERROR,
61
Gtk.ButtonsType.NONE, err)
62
winError.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
63
_("Backup"), Gtk.ResponseType.ACCEPT)
66
if resp == Gtk.ResponseType.ACCEPT:
67
self.backup_datafile()
69
self.nset.load_fresh()
71
# If all notes were visible previously, show them now
72
if self.nset.properties.get("all_visible", True):
28
self.nset = NoteSet(StickyNote)
74
31
# Create App Indicator
75
32
self.ind = appindicator.Indicator.new(
76
33
"Sticky Notes", "indicator-stickynotes",
77
34
appindicator.IndicatorCategory.APPLICATION_STATUS)
78
# Delete/modify the following file when distributing as a package
79
self.ind.set_icon_theme_path(os.path.abspath(os.path.join(
80
os.path.dirname(__file__), 'Icons')))
81
self.ind.set_icon("indicator-stickynotes")
82
35
self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
83
self.ind.set_title(_("Sticky Notes"))
36
self.ind.set_title("Sticky Notes")
37
#self.ind.set_attention_icon("pynagram")
85
39
self.menu = Gtk.Menu()
86
self.mNewNote = Gtk.MenuItem(_("New Note"))
40
self.mNewNote = Gtk.MenuItem("New Note")
87
41
self.menu.append(self.mNewNote)
88
42
self.mNewNote.connect("activate", self.new_note, None)
89
43
self.mNewNote.show()
120
74
self.menu.append(s)
123
self.mExport = Gtk.MenuItem(_("Export Data"))
124
self.menu.append(self.mExport)
125
self.mExport.connect("activate", self.export_datafile, None)
128
self.mImport = Gtk.MenuItem(_("Import Data"))
129
self.menu.append(self.mImport)
130
self.mImport.connect("activate", self.import_datafile, None)
133
s = Gtk.SeparatorMenuItem.new()
137
self.mAbout = Gtk.MenuItem(_("About"))
138
self.menu.append(self.mAbout)
139
self.mAbout.connect("activate", self.show_about, None)
142
self.mSettings = Gtk.MenuItem(_("Settings"))
143
self.menu.append(self.mSettings)
144
self.mSettings.connect("activate", self.show_settings, None)
145
self.mSettings.show()
147
s = Gtk.SeparatorMenuItem.new()
151
self.mQuit = Gtk.MenuItem(_("Quit"))
77
self.mQuit = Gtk.MenuItem("Quit")
152
78
self.menu.append(self.mQuit)
153
79
self.mQuit.connect("activate", Gtk.main_quit, None)
155
81
# Connect Indicator to menu
156
82
self.ind.set_menu(self.menu)
158
# Define secondary action (middle click)
159
self.connect_secondary_activate()
161
84
def new_note(self, *args):
164
87
def showall(self, *args):
165
88
self.nset.showall(*args)
166
self.connect_secondary_activate()
168
90
def hideall(self, *args):
169
91
self.nset.hideall()
170
self.connect_secondary_activate()
172
def connect_secondary_activate(self):
173
"""Define action of secondary action (middle click) depending
174
on visibility state of notes."""
175
if self.nset.properties["all_visible"] == True:
176
self.ind.set_secondary_activate_target(self.mHideAll)
178
self.ind.set_secondary_activate_target(self.mShowAll)
182
93
def lockall(self, *args):
183
94
for note in self.nset.notes:
184
note.set_locked_state(True)
95
note.gui.set_locked_state(True)
187
97
def unlockall(self, *args):
188
98
for note in self.nset.notes:
189
note.set_locked_state(False)
191
def backup_datafile(self):
192
winChoose = Gtk.FileChooserDialog(_("Export Data"), None,
193
Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL,
194
Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE,
195
Gtk.ResponseType.ACCEPT))
196
winChoose.set_do_overwrite_confirmation(True)
197
response = winChoose.run()
199
if response == Gtk.ResponseType.ACCEPT:
200
backupfile = winChoose.get_filename()
204
copyfile(os.path.expanduser(self.data_file), backupfile)
205
except SameFileError:
206
err = _("Please choose a different "
207
"destination for the backup file.")
208
winError = Gtk.MessageDialog(None, None,
209
Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, err)
212
self.backup_datafile()
214
def export_datafile(self, *args):
215
self.backup_datafile()
217
def import_datafile(self, *args):
218
winChoose = Gtk.FileChooserDialog(_("Import Data"), None,
219
Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL,
220
Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN,
221
Gtk.ResponseType.ACCEPT))
222
response = winChoose.run()
224
if response == Gtk.ResponseType.ACCEPT:
225
backupfile = winChoose.get_filename()
229
with open(backupfile, encoding="utf-8") as fsock:
230
self.nset.merge(fsock.read())
231
except Exception as e:
232
err = _("Error importing data.")
233
winError = Gtk.MessageDialog(None, None,
234
Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, err)
238
def show_about(self, *args):
241
def show_settings(self, *args):
242
wSettings = SettingsDialog(self.nset)
99
note.gui.set_locked_state(False)
250
locale.setlocale(locale.LC_ALL, '')
252
locale.setlocale(locale.LC_ALL, 'C')
253
# If we're running from /usr, then .mo files are not in MO_DIR.
254
if os.path.abspath(__file__)[:4] == '/usr':
255
# Fallback to default
258
locale_dir = os.path.join(os.path.dirname(__file__), MO_DIR)
259
locale.bindtextdomain(LOCALE_DOMAIN, locale_dir)
260
locale.textdomain(LOCALE_DOMAIN)
262
parser = argparse.ArgumentParser(description=_("Sticky Notes"))
263
parser.add_argument("-d", action='store_true', help="use the development"
265
args = parser.parse_args()
267
indicator = IndicatorStickyNotes(args)
268
# Load global css for the first time.
106
indicator = IndicatorStickyNotes()