summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2014-01-30 16:04:57 +0100
committerStefano Karapetsas <[email protected]>2014-01-30 16:04:57 +0100
commit8795f06d464700494234e589020e5e29854aeb8c (patch)
treef2525b646023e533f03d5c80240563b89ab5b152
parentc8a85a6aa040c1d2505b957af4cfb4bd39466504 (diff)
parent064212a25bea1fcf8901cd0a1d55aae0899f627c (diff)
downloadmate-applets-8795f06d464700494234e589020e5e29854aeb8c.tar.bz2
mate-applets-8795f06d464700494234e589020e5e29854aeb8c.tar.xz
Merge branch 'dev-timer-applet'
Closes #45 https://github.com/mate-desktop/mate-applets/issues/45
-rw-r--r--Makefile.am8
-rw-r--r--configure.ac26
-rw-r--r--po/POTFILES.in2
-rw-r--r--timer-applet/AUTHORS2
-rw-r--r--timer-applet/Makefile.am1
-rw-r--r--timer-applet/data/Makefile.am27
-rw-r--r--timer-applet/data/TimerApplet.server.in.in22
-rw-r--r--timer-applet/data/TimerApplet.xml19
-rw-r--r--timer-applet/data/timer-applet.glade1302
-rw-r--r--timer-applet/data/timer-applet.schemas.in87
-rw-r--r--timer-applet/images/Makefile.am5
-rw-r--r--timer-applet/images/timer-applet.pngbin2820 -> 0 bytes
-rw-r--r--timer-applet/images/timer-applet.svg725
-rw-r--r--timer-applet/src/Makefile.am6
-rwxr-xr-xtimer-applet/src/timer-applet136
-rw-r--r--timer-applet/src/timerapplet/Makefile.am27
-rw-r--r--timer-applet/src/timerapplet/__init__.py1
-rw-r--r--timer-applet/src/timerapplet/config.py39
-rw-r--r--timer-applet/src/timerapplet/controllers/GlobalController.py91
-rw-r--r--timer-applet/src/timerapplet/controllers/Makefile.am8
-rw-r--r--timer-applet/src/timerapplet/controllers/TimerApplet.py637
-rw-r--r--timer-applet/src/timerapplet/controllers/TimerManagerService.py42
-rw-r--r--timer-applet/src/timerapplet/controllers/TimerService.py49
-rw-r--r--timer-applet/src/timerapplet/controllers/__init__.py20
-rw-r--r--timer-applet/src/timerapplet/core/AppletMateConfWrapper.py89
-rw-r--r--timer-applet/src/timerapplet/core/Makefile.am6
-rw-r--r--timer-applet/src/timerapplet/core/PresetsStore.py160
-rw-r--r--timer-applet/src/timerapplet/core/Timer.py175
-rw-r--r--timer-applet/src/timerapplet/core/__init__.py19
-rw-r--r--timer-applet/src/timerapplet/defs.py.in7
-rw-r--r--timer-applet/src/timerapplet/logger.py23
-rw-r--r--timer-applet/src/timerapplet/ui/AddEditPresetDialog.py75
-rw-r--r--timer-applet/src/timerapplet/ui/ContinueTimerDialog.py63
-rw-r--r--timer-applet/src/timerapplet/ui/DurationChooser.py166
-rw-r--r--timer-applet/src/timerapplet/ui/Makefile.am15
-rw-r--r--timer-applet/src/timerapplet/ui/ManagePresetsDialog.py86
-rw-r--r--timer-applet/src/timerapplet/ui/Notifier.py73
-rw-r--r--timer-applet/src/timerapplet/ui/PieMeter.py77
-rw-r--r--timer-applet/src/timerapplet/ui/PreferencesDialog.py192
-rw-r--r--timer-applet/src/timerapplet/ui/PulseButton.py69
-rw-r--r--timer-applet/src/timerapplet/ui/ScrollableButtonList.py65
-rw-r--r--timer-applet/src/timerapplet/ui/StartNextTimerDialog.py66
-rw-r--r--timer-applet/src/timerapplet/ui/StartTimerDialog.py267
-rw-r--r--timer-applet/src/timerapplet/ui/StatusButton.py101
-rw-r--r--timer-applet/src/timerapplet/ui/__init__.py28
-rw-r--r--timer-applet/src/timerapplet/utils.py79
-rw-r--r--timerapplet/Makefile.am45
-rw-r--r--timerapplet/org.mate.applets.TimerApplet.mate-panel-applet.in.in10
-rw-r--r--timerapplet/org.mate.panel.applet.TimerAppletFactory.service.in3
-rw-r--r--timerapplet/org.mate.panel.applet.timer.gschema.xml.in.in20
-rw-r--r--timerapplet/timerapplet.c448
51 files changed, 540 insertions, 5169 deletions
diff --git a/Makefile.am b/Makefile.am
index 537372ce..0e988730 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,8 +35,8 @@ if BUILD_INVEST_APPLET
invest_applet_SUBDIR = invest-applet
endif
-if BUILD_TIMER_APPLET
-timer_applet_SUBDIR = timer-applet
+if BUILD_TIMERAPPLET
+timerapplet_SUBDIR = timerapplet
endif
always_built_SUBDIRS = \
@@ -59,7 +59,7 @@ SUBDIRS = \
$(accessx_status_SUBDIR) \
$(invest_applet_SUBDIR) \
$(cpufreq_SUBDIR) \
- $(timer_applet_SUBDIR)
+ $(timerapplet_SUBDIR)
DIST_SUBDIRS = \
po \
@@ -73,10 +73,10 @@ DIST_SUBDIRS = \
man \
accessx-status \
stickynotes \
+ timerapplet \
trashapplet \
cpufreq \
invest-applet \
- timer-applet \
command \
null_applet
diff --git a/configure.ac b/configure.ac
index 02318101..ec379921 100644
--- a/configure.ac
+++ b/configure.ac
@@ -443,15 +443,6 @@ fi
AM_CONDITIONAL(BUILD_STICKYNOTES_APPLET, test "x$enable_stickynotes" = "xyes")
dnl ***************************************************************************
-dnl *** Timer applet specific checks ***
-dnl ***************************************************************************
-AC_ARG_ENABLE([timer-applet],
- AC_HELP_STRING([--enable-timer-applet], [Enable the timer applet.]),
- enable_timerapplet=$enableval,
- enable_timerapplet=no)
-AM_CONDITIONAL(BUILD_TIMER_APPLET, test "x$enable_timerapplet" = "xyes")
-
-dnl ***************************************************************************
dnl *** keyboard accessibility status applet check ***
dnl ***************************************************************************
@@ -548,6 +539,12 @@ AM_CONDITIONAL(BUILD_CPUFREQ_SELECTOR, test x$enable_selector = xyes)
AM_CONDITIONAL(CPUFREQ_SELECTOR_SUID, test x$suid = xyes)
dnl ***************************************************************************
+dnl *** timerapplet specific checks ***
+dnl ***************************************************************************
+
+AM_CONDITIONAL(BUILD_TIMERAPPLET, test "x$HAVE_LIBNOTIFY" = "xyes")
+
+dnl ***************************************************************************
dnl *** invest-applet specific checks ***
dnl ***************************************************************************
@@ -703,14 +700,7 @@ cpufreq/src/Makefile
cpufreq/src/cpufreq-selector/Makefile
cpufreq/pixmaps/Makefile
cpufreq/help/Makefile
-timer-applet/Makefile
-timer-applet/data/Makefile
-timer-applet/images/Makefile
-timer-applet/src/Makefile
-timer-applet/src/timerapplet/Makefile
-timer-applet/src/timerapplet/controllers/Makefile
-timer-applet/src/timerapplet/core/Makefile
-timer-applet/src/timerapplet/ui/Makefile
+timerapplet/Makefile
command/Makefile
null_applet/Makefile
])
@@ -743,8 +733,8 @@ mate-applets-$VERSION configure summary:
- modemlights $BUILD_MODEM_LIGHTS
- multiload $build_gtop_applets
- stickynotes $enable_stickynotes
+ - timerapplet $HAVE_LIBNOTIFY
- trashapplet always
- - timer-applet $enable_timerapplet
Using DBUS: $HAVE_DBUS
Using NetworkManager: $HAVE_NETWORKMANAGER
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 60211e55..3544bb59 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -78,6 +78,8 @@ stickynotes/org.mate.stickynotes.gschema.xml.in.in
stickynotes/stickynotes_applet.c
stickynotes/stickynotes_applet_callbacks.c
stickynotes/stickynotes_callbacks.c
+timerapplet/org.mate.panel.applet.timer.gschema.xml.in.in
+timerapplet/timerapplet.c
timer-applet/data/TimerApplet.server.in.in
timer-applet/data/TimerApplet.xml
timer-applet/data/timer-applet.glade
diff --git a/timer-applet/AUTHORS b/timer-applet/AUTHORS
deleted file mode 100644
index a12bc88c..00000000
--- a/timer-applet/AUTHORS
+++ /dev/null
@@ -1,2 +0,0 @@
-Jimmy Do <[email protected]>
-Stefano Karapetsas <[email protected]>
diff --git a/timer-applet/Makefile.am b/timer-applet/Makefile.am
deleted file mode 100644
index 106cc3f9..00000000
--- a/timer-applet/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = data images src
diff --git a/timer-applet/data/Makefile.am b/timer-applet/data/Makefile.am
deleted file mode 100644
index 49f3b908..00000000
--- a/timer-applet/data/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-serverdir = $(libdir)/matecomponent/servers
-server_in_files = TimerApplet.server.in
-server_DATA = $(server_in_files:.server.in=.server)
-
-$(server_in_files): $(server_in_files:.server.in=.server.in.in) Makefile
- sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@
-
-schemasdir = $(MATECONF_SCHEMA_FILE_DIR)
-schemas_in_files = timer-applet.schemas.in
-schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
-
-pkgdata_DATA = \
- TimerApplet.xml \
- timer-applet.glade
-
-EXTRA_DIST = \
- TimerApplet.server.in.in \
- $(pkgdata_DATA) \
- $(schemas_in_files)
-
-CLEANFILES = \
- $(server_DATA) \
- $(server_in_files) \
- $(schemas_DATA)
-
-@INTLTOOL_SERVER_RULE@
-@INTLTOOL_SCHEMAS_RULE@
diff --git a/timer-applet/data/TimerApplet.server.in.in b/timer-applet/data/TimerApplet.server.in.in
deleted file mode 100644
index 5c7a826d..00000000
--- a/timer-applet/data/TimerApplet.server.in.in
+++ /dev/null
@@ -1,22 +0,0 @@
-<oaf_info>
-<oaf_server iid="OAFIID:TimerApplet_Factory" type="exe" location="@LIBEXECDIR@/timer-applet">
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:MateComponent/GenericFactory:1.0"/>
- <item value="IDL:MateComponent/Unknown:1.0"/>
- </oaf_attribute>
- <oaf_attribute name="name" type="string" _value="Timer Applet Factory"/>
- <oaf_attribute name="description" type="string" _value="A Timer Applet factory that creates Timer Applets"/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:TimerApplet" type="factory" location="OAFIID:TimerApplet_Factory">
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:MATE/Vertigo/MatePanelAppletShell:1.0"/>
- <item value="IDL:MateComponent/Control:1.0"/>
- <item value="IDL:MateComponent/Unknown:1.0"/>
- </oaf_attribute>
- <oaf_attribute name="name" type="string" _value="Timer"/>
- <oaf_attribute name="description" type="string" _value="Start a timer and receive a notification when it is finished"/>
- <oaf_attribute name="panel:category" type="string" value="Accessories"/>
- <oaf_attribute name="panel:icon" type="string" value="timer-applet.png"/>
-</oaf_server>
-</oaf_info>
diff --git a/timer-applet/data/TimerApplet.xml b/timer-applet/data/TimerApplet.xml
deleted file mode 100644
index 67df361c..00000000
--- a/timer-applet/data/TimerApplet.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Root>
- <popups>
- <popup name="button3">
- <menuitem verb="PauseTimer" name="Pause Item" _label="Pa_use"/>
- <menuitem verb="ContinueTimer" name="Continue Item" _label="_Continue"/>
- <menuitem verb="StopTimer" name="Stop Item" _label="_Stop"/>
- <menuitem verb="RestartTimer" name="Restart Item" _label="R_estart"/>
- <menuitem verb="StartNextTimer" name="Start next item" _label="Next"/>
- <submenu name="Presets" _label="Pre_sets">
- </submenu>
- <separator name="Separator1"/>
- <menuitem verb="ManagePresets" name="Manage Presets Item" _label="Ma_nage Presets"/>
- <menuitem verb="Preferences" pixtype="stock" pixname="gtk-properties" name="Preferences Item" _label="_Preferences"/>
- <menuitem verb="About" pixtype="stock" pixname="mate-stock-about" name="About Item" _label="_About"/>
- </popup>
- </popups>
-</Root>
-
diff --git a/timer-applet/data/timer-applet.glade b/timer-applet/data/timer-applet.glade
deleted file mode 100644
index 2ac443e6..00000000
--- a/timer-applet/data/timer-applet.glade
+++ /dev/null
@@ -1,1302 +0,0 @@
-<?xml version="1.0"?>
-<glade-interface>
- <!-- interface-requires gtk+ 2.6 -->
- <!-- interface-naming-policy toplevel-contextual -->
- <widget class="GtkDialog" id="start_timer_dialog">
- <property name="title" translatable="yes">Start Timer</property>
- <property name="type_hint">dialog</property>
- <property name="has_separator">False</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkVBox" id="vbox9">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <child>
- <widget class="GtkVBox" id="duration_and_name_vbox">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <widget class="GtkVBox" id="duration_chooser_container">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <widget class="GtkLabel" id="name_label">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">name_entry</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="name_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="activates_default">True</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkExpander" id="expander_command">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkFrame" id="frame1">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <child>
- <widget class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <child>
- <widget class="GtkComboBoxEntry" id="next_timer_combo_entry">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="y_padding">3</property>
- </packing>
- </child>
- <child>
- <widget class="GtkCheckButton" id="auto_start_check">
- <property name="label" translatable="yes">Start automatically</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_padding">3</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Define next timer&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkFrame" id="frame2">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="border_width">3</property>
- <child>
- <widget class="GtkLabel" id="command_label">
- <property name="width_request">50</property>
- <property name="visible">True</property>
- <property name="has_tooltip">True</property>
- <property name="ypad">5</property>
- <property name="label" translatable="yes">Execute:</property>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="command_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <signal name="changed" handler="command_entry_changed_cb"/>
- </widget>
- <packing>
- <property name="padding">5</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Run custom command&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="invalid_command_label">
- <property name="visible">True</property>
- <property name="app_paintable">True</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label_command">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Run executable after timer finished.</property>
- <property name="label" translatable="yes">Advanced</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHButtonBox" id="hbuttonbox1">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="save_button">
- <property name="label" translatable="yes">S_ave as Preset</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <widget class="GtkFrame" id="presets_section">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment6">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkVBox" id="vbox7">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">6</property>
- <child>
- <widget class="GtkVBox" id="presets_chooser_container">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="manage_presets_button">
- <property name="label" translatable="yes">Mana_ge Presets</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">&lt;b&gt;_Presets&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="cancelbutton1">
- <property name="label">gtk-cancel</property>
- <property name="response_id">-6</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="ok_button">
- <property name="label" translatable="yes">S_tart Timer</property>
- <property name="response_id">-5</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkDialog" id="manage_presets_dialog">
- <property name="title" translatable="yes">Manage Presets</property>
- <property name="type_hint">dialog</property>
- <property name="has_separator">False</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox2">
- <property name="visible">True</property>
- <child>
- <widget class="GtkFrame" id="frame1">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">in</property>
- <child>
- <widget class="GtkTreeView" id="presets_view">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox4">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <widget class="GtkButton" id="delete_button">
- <property name="label" translatable="yes">_Delete</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="edit_button">
- <property name="label" translatable="yes">_Edit...</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="add_button">
- <property name="label" translatable="yes">_Add...</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;_Presets&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area2">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="close_button">
- <property name="label">gtk-close</property>
- <property name="response_id">-7</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkDialog" id="preferences_dialog">
- <property name="title" translatable="yes">Timer Preferences</property>
- <property name="default_height">189</property>
- <property name="type_hint">dialog</property>
- <property name="has_separator">False</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox3">
- <property name="visible">True</property>
- <child>
- <widget class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <child>
- <widget class="GtkCheckButton" id="show_time_check">
- <property name="label" translatable="yes">_Show remaining time while timer is running</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="vbox6">
- <property name="visible">True</property>
- <child>
- <widget class="GtkCheckButton" id="play_sound_check">
- <property name="label" translatable="yes">_Play notification sound</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="play_sound_box">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <widget class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkRadioButton" id="use_default_sound_radio">
- <property name="label" translatable="yes">Use d_efault sound</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <child>
- <widget class="GtkRadioButton" id="use_custom_sound_radio">
- <property name="label" translatable="yes">Use c_ustom sound</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">use_default_sound_radio</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkAlignment" id="alignment5">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkFileChooserButton" id="sound_chooser_button">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="title" translatable="yes">Choose A Sound File</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkCheckButton" id="popup_notification_check">
- <property name="label" translatable="yes">_Show popup notification</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip" translatable="yes">_Show popup notification after timer has ended.</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkCheckButton" id="pulsing_trayicon_check">
- <property name="label" translatable="yes">S_how pulsing panel icon</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip" translatable="yes">Show pulsing panel icon after timer has ended.</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area3">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="close_button">
- <property name="label">gtk-close</property>
- <property name="response_id">-7</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkDialog" id="add_edit_preset_dialog">
- <property name="title" translatable="yes">Add Preset</property>
- <property name="type_hint">dialog</property>
- <property name="has_separator">False</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox4">
- <property name="visible">True</property>
- <child>
- <widget class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <child>
- <widget class="GtkFrame" id="frame2">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <property name="right_padding">12</property>
- <child>
- <widget class="GtkEntry" id="name_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="activates_default">True</property>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="name_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;_Name&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkFrame" id="frame3">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment3">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <widget class="GtkVBox" id="duration_chooser_container">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;_Duration&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- <property name="use_underline">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkFrame" id="frame1">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <property name="right_padding">12</property>
- <child>
- <widget class="GtkEntry" id="command_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Run custom command after timer has ended.</property>
- <property name="label" translatable="yes">&lt;b&gt;Custom command&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkFrame" id="frame4">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <widget class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <property name="right_padding">12</property>
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkEntry" id="next_timer_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkCheckButton" id="auto_start_check">
- <property name="label" translatable="yes">Initiate automatically</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Interval timer&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area4">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <widget class="GtkButton" id="cancel_button">
- <property name="label">gtk-cancel</property>
- <property name="response_id">-6</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="ok_button">
- <property name="label">gtk-save</property>
- <property name="response_id">-5</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <widget class="GtkAboutDialog" id="about_dialog">
- <property name="window_position">center</property>
- <property name="type_hint">normal</property>
- <property name="copyright">Copyright (c) 2010 by Kenny Meyer.
-Copyright (c) 2007 by Jimmy Do</property>
- <property name="comments" translatable="yes">A timer applet for the perfect egg and beyond!</property>
- <property name="website">https://launchpad.net/timer-applet</property>
- <property name="website_label" translatable="yes">Timer Applet</property>
- <property name="license"> GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geomraphical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- &lt;one line to give the program's name and a brief idea of what it does.&gt;
- Copyright (C) &lt;year&gt; &lt;name of author&gt;
-
- This program 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 2 of the License, or
- (at your option) any later version.
-
- This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- &lt;signature of Ty Coon&gt;, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.</property>
- <property name="authors">Jimmy Do &lt;[email protected]&gt;</property>
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox5">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area5">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
-</glade-interface>
diff --git a/timer-applet/data/timer-applet.schemas.in b/timer-applet/data/timer-applet.schemas.in
deleted file mode 100644
index eadc902a..00000000
--- a/timer-applet/data/timer-applet.schemas.in
+++ /dev/null
@@ -1,87 +0,0 @@
-<mateconfschemafile>
- <schemalist>
- <schema>
- <key>/schemas/apps/timer-applet/prefs/play_notification_sound</key>
- <applyto>/apps/timer-applet/prefs/play_notification_sound</applyto>
- <owner>timer-applet</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Play notification sound</short>
- <long>Play a notification sound when the timer finishes a countdown</long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/timer-applet/prefs/use_custom_notification_sound</key>
- <applyto>/apps/timer-applet/prefs/use_custom_notification_sound</applyto>
- <owner>timer-applet</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Use a custom notification sound</short>
- <long>Use the custom notification sound specified in custom_notification_sound_path</long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/timer-applet/prefs/custom_notification_sound_path</key>
- <applyto>/apps/timer-applet/prefs/custom_notification_sound_path</applyto>
- <owner>timer-applet</owner>
- <type>string</type>
- <default></default>
- <locale name="C">
- <short>Path to a custom notification sound</short>
- <long>Path to a sound file that will be played when the timer finishes a countdown</long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/timer-applet/prefs/show_pulsing_icon</key>
- <applyto>/apps/timer-applet/prefs/show_pulsing_icon</applyto>
- <owner>timer-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short>Show Pulsing icon</short>
- <long>Show pulsing tray icon when timer finished</long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/timer-applet/prefs/show_popup_notification</key>
- <applyto>/apps/timer-applet/prefs/show_popup_notification</applyto>
- <owner>timer-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short>Show Popup notification</short>
- <long>Show Popup notification in the notification area</long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/timer-applet/prefs/show_remaining_time</key>
- <applyto>/apps/timer-applet/prefs/show_remaining_time</applyto>
- <owner>timer-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short>Show remaining time</short>
- <long>Show the remaining time while the timer is running or paused</long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/timer-applet/prefs/play_beep</key>
- <applyto>/apps/timer-applet/prefs/play_beep</applyto>
- <owner>timer-applet</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short>Play a beep sound</short>
- <long>Play a beep sound on a computer's internal speaker when the timer finishes. This may not have an effect on all computers.</long>
- </locale>
- </schema>
- </schemalist>
-</mateconfschemafile>
diff --git a/timer-applet/images/Makefile.am b/timer-applet/images/Makefile.am
deleted file mode 100644
index fd039a73..00000000
--- a/timer-applet/images/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-icondir = $(datadir)/pixmaps
-icon_DATA = timer-applet.png
-
-EXTRA_DIST = $(icon_DATA)
-
diff --git a/timer-applet/images/timer-applet.png b/timer-applet/images/timer-applet.png
deleted file mode 100644
index cb54c3c6..00000000
--- a/timer-applet/images/timer-applet.png
+++ /dev/null
Binary files differ
diff --git a/timer-applet/images/timer-applet.svg b/timer-applet/images/timer-applet.svg
deleted file mode 100644
index 8378578e..00000000
--- a/timer-applet/images/timer-applet.svg
+++ /dev/null
@@ -1,725 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="48"
- height="48"
- id="svg3319"
- sodipodi:version="0.32"
- inkscape:version="0.45"
- version="1.0"
- sodipodi:docbase="/home/jimmy/Desktop"
- sodipodi:docname="drawing3.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- sodipodi:modified="true">
- <defs
- id="defs3321">
- <linearGradient
- id="linearGradient4195"
- inkscape:collect="always">
- <stop
- id="stop4197"
- offset="0"
- style="stop-color:#eeeeee;stop-opacity:1;" />
- <stop
- id="stop4199"
- offset="1"
- style="stop-color:#a6a6a6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient4181">
- <stop
- style="stop-color:#1e1e1e;stop-opacity:1"
- offset="0"
- id="stop4183" />
- <stop
- style="stop-color:#000000;stop-opacity:0"
- offset="1"
- id="stop4185" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3760">
- <stop
- style="stop-color:#969696;stop-opacity:1"
- offset="0"
- id="stop3762" />
- <stop
- style="stop-color:#adadad;stop-opacity:1"
- offset="1"
- id="stop3764" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3752">
- <stop
- style="stop-color:#414141;stop-opacity:1"
- offset="0"
- id="stop3754" />
- <stop
- style="stop-color:#cacaca;stop-opacity:1"
- offset="1"
- id="stop3756" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3736">
- <stop
- style="stop-color:#5c5f67;stop-opacity:1"
- offset="0"
- id="stop3738" />
- <stop
- style="stop-color:#d6d7db;stop-opacity:1"
- offset="1"
- id="stop3740" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3728">
- <stop
- style="stop-color:#54565e;stop-opacity:1;"
- offset="0"
- id="stop3730" />
- <stop
- style="stop-color:#d9dadd;stop-opacity:1"
- offset="1"
- id="stop3732" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3629">
- <stop
- style="stop-color:#eeeeee;stop-opacity:1;"
- offset="0"
- id="stop3631" />
- <stop
- style="stop-color:#b1b1b1;stop-opacity:1"
- offset="1"
- id="stop3633" />
- </linearGradient>
- <linearGradient
- id="linearGradient3623"
- inkscape:collect="always">
- <stop
- id="stop3625"
- offset="0"
- style="stop-color:#535353;stop-opacity:1;" />
- <stop
- id="stop3627"
- offset="1"
- style="stop-color:#eeeeee;stop-opacity:0.50282484" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3612">
- <stop
- style="stop-color:#535353;stop-opacity:1;"
- offset="0"
- id="stop3614" />
- <stop
- style="stop-color:#535353;stop-opacity:0;"
- offset="1"
- id="stop3616" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3604">
- <stop
- style="stop-color:#535353;stop-opacity:1;"
- offset="0"
- id="stop3606" />
- <stop
- style="stop-color:#535353;stop-opacity:0;"
- offset="1"
- id="stop3608" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3596">
- <stop
- style="stop-color:#535353;stop-opacity:1;"
- offset="0"
- id="stop3598" />
- <stop
- style="stop-color:#535353;stop-opacity:0;"
- offset="1"
- id="stop3600" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3588">
- <stop
- style="stop-color:#535353;stop-opacity:1;"
- offset="0"
- id="stop3590" />
- <stop
- style="stop-color:#535353;stop-opacity:0;"
- offset="1"
- id="stop3592" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3580">
- <stop
- style="stop-color:#535353;stop-opacity:1;"
- offset="0"
- id="stop3582" />
- <stop
- style="stop-color:#535353;stop-opacity:0;"
- offset="1"
- id="stop3584" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3504">
- <stop
- style="stop-color:#353535;stop-opacity:1;"
- offset="0"
- id="stop3506" />
- <stop
- style="stop-color:#656565;stop-opacity:1"
- offset="1"
- id="stop3508" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3460">
- <stop
- style="stop-color:#2e3436;stop-opacity:1;"
- offset="0"
- id="stop3462" />
- <stop
- style="stop-color:#7c7c7c;stop-opacity:1"
- offset="1"
- id="stop3464" />
- </linearGradient>
- <linearGradient
- id="linearGradient3452">
- <stop
- id="stop3454"
- offset="0"
- style="stop-color:#6e6e6e;stop-opacity:1;" />
- <stop
- style="stop-color:#b4b4b4;stop-opacity:1;"
- offset="0.5"
- id="stop3456" />
- <stop
- id="stop3458"
- offset="1"
- style="stop-color:#6e6e6e;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3440">
- <stop
- style="stop-color:#969696;stop-opacity:1;"
- offset="0"
- id="stop3442" />
- <stop
- id="stop3450"
- offset="0.5"
- style="stop-color:#d2d2d2;stop-opacity:1;" />
- <stop
- style="stop-color:#969696;stop-opacity:1;"
- offset="1"
- id="stop3444" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3358">
- <stop
- style="stop-color:#ebeceb;stop-opacity:1"
- offset="0"
- id="stop3360" />
- <stop
- style="stop-color:#82847f;stop-opacity:1"
- offset="1"
- id="stop3362" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3358"
- id="linearGradient3380"
- gradientUnits="userSpaceOnUse"
- x1="23.132887"
- y1="9.5372581"
- x2="24.583008"
- y2="36.468082"
- gradientTransform="matrix(1,0,0,-1,0.2614378,42.815504)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3358"
- id="linearGradient3393"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,-1,5.4277591e-2,37.567445)"
- x1="23.132887"
- y1="9.5372581"
- x2="24.583008"
- y2="36.468082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3358"
- id="linearGradient3406"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,-1,5.4277591e-2,37.567445)"
- x1="23.132887"
- y1="9.5372581"
- x2="24.583008"
- y2="36.468082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3358"
- id="linearGradient3410"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,-1,5.4277591e-2,37.567445)"
- x1="23.132887"
- y1="9.5372581"
- x2="24.583008"
- y2="36.468082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3452"
- id="linearGradient3438"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,-1,0.8829184,34.874362)"
- x1="3.2975602"
- y1="-2.7816784"
- x2="43.998512"
- y2="-2.7816784" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3440"
- id="linearGradient3446"
- x1="7.5087595"
- y1="22.312136"
- x2="42.753796"
- y2="22.312136"
- gradientUnits="userSpaceOnUse"
- spreadMethod="pad" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3460"
- id="linearGradient3466"
- x1="25.795841"
- y1="28.020357"
- x2="24.873999"
- y2="3.4578571"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4195"
- id="linearGradient3502"
- x1="24.833334"
- y1="25.916666"
- x2="23.916668"
- y2="15.041666"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3504"
- id="linearGradient3510"
- x1="27.875"
- y1="29.25"
- x2="24.138199"
- y2="5.833334"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3580"
- id="linearGradient3586"
- x1="26.77684"
- y1="28.044653"
- x2="28.586987"
- y2="29.712654"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3588"
- id="linearGradient3594"
- x1="26.763739"
- y1="15.459818"
- x2="28.632809"
- y2="13.732889"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3596"
- id="linearGradient3602"
- x1="22.943235"
- y1="15.459818"
- x2="20.897388"
- y2="13.497188"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3604"
- id="linearGradient3610"
- x1="22.956337"
- y1="28.044653"
- x2="21.146193"
- y2="29.77158"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3612"
- id="linearGradient3618"
- x1="45.136982"
- y1="14.765982"
- x2="47.611858"
- y2="21.012091"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3623"
- id="linearGradient3621"
- gradientUnits="userSpaceOnUse"
- x1="25.691545"
- y1="26.315392"
- x2="30.05204"
- y2="29.202744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient3635"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9942059,0,0,1.1100452,0.144079,-2.2891677)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3728"
- id="linearGradient3734"
- x1="24.188944"
- y1="13.705321"
- x2="24.13002"
- y2="14.97222"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3736"
- id="linearGradient3742"
- x1="24.875"
- y1="29.084894"
- x2="24.875"
- y2="27.847456"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3752"
- id="linearGradient3758"
- x1="21.920311"
- y1="27.99477"
- x2="22.09375"
- y2="16.828377"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3760"
- id="linearGradient3766"
- x1="27.606627"
- y1="26.963573"
- x2="27.625"
- y2="16.828377"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4181"
- id="radialGradient4187"
- cx="25.573694"
- cy="38.689762"
- fx="25.573694"
- fy="38.689762"
- r="20.977501"
- gradientTransform="matrix(1,0,0,0.1460674,0,33.038449)"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4195"
- id="linearGradient2246"
- gradientUnits="userSpaceOnUse"
- x1="24.833334"
- y1="25.916666"
- x2="23.916668"
- y2="15.041666" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3504"
- id="linearGradient2248"
- gradientUnits="userSpaceOnUse"
- x1="27.875"
- y1="29.25"
- x2="24.138199"
- y2="5.833334" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient2250"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9942059,0,0,1.1100452,0.144079,-2.2891677)"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient2247"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9605798,0,0,0.9793075,0.9789654,0.277812)"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4181"
- id="radialGradient2256"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,0.1460674,0,33.038449)"
- cx="25.573694"
- cy="38.689762"
- fx="25.573694"
- fy="38.689762"
- r="20.977501" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3452"
- id="linearGradient2258"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,-1,0.8829184,34.874362)"
- x1="3.2975602"
- y1="-2.7816784"
- x2="43.998512"
- y2="-2.7816784" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3440"
- id="linearGradient2260"
- gradientUnits="userSpaceOnUse"
- spreadMethod="pad"
- x1="7.5087595"
- y1="22.312136"
- x2="42.753796"
- y2="22.312136" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3460"
- id="linearGradient2262"
- gradientUnits="userSpaceOnUse"
- x1="25.795841"
- y1="28.020357"
- x2="24.873999"
- y2="3.4578571" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4195"
- id="linearGradient2264"
- gradientUnits="userSpaceOnUse"
- x1="24.833334"
- y1="25.916666"
- x2="23.916668"
- y2="15.041666" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3504"
- id="linearGradient2266"
- gradientUnits="userSpaceOnUse"
- x1="27.875"
- y1="29.25"
- x2="24.138199"
- y2="5.833334" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient2268"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9605798,0,0,0.9793075,0.9789654,0.277812)"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient2271"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9605798,0,0,0.9793075,0.2110192,0.277812)"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3460"
- id="linearGradient2275"
- gradientUnits="userSpaceOnUse"
- x1="25.795841"
- y1="28.020357"
- x2="24.873999"
- y2="3.4578571"
- gradientTransform="translate(-0.7679462,0)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3440"
- id="linearGradient2280"
- gradientUnits="userSpaceOnUse"
- spreadMethod="pad"
- x1="7.5087595"
- y1="22.312136"
- x2="42.753796"
- y2="22.312136"
- gradientTransform="translate(-0.7679462,0)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3452"
- id="linearGradient2283"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,-1,0.1149722,34.874362)"
- x1="3.2975602"
- y1="-2.7816784"
- x2="43.998512"
- y2="-2.7816784" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4181"
- id="radialGradient2286"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,0.1460674,0,33.038449)"
- cx="25.573694"
- cy="38.689762"
- fx="25.573694"
- fy="38.689762"
- r="20.977501" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4195"
- id="linearGradient2292"
- gradientUnits="userSpaceOnUse"
- x1="24.833334"
- y1="25.916666"
- x2="23.916668"
- y2="15.041666" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3504"
- id="linearGradient2294"
- gradientUnits="userSpaceOnUse"
- x1="27.875"
- y1="29.25"
- x2="24.138199"
- y2="5.833334" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient2296"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9605798,0,0,0.9793075,0.2110192,0.277812)"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3629"
- id="linearGradient2299"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9605798,0,0,0.9793075,0.2197079,-0.3819568)"
- x1="24.513035"
- y1="16.85784"
- x2="24.660349"
- y2="25.696674" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- gridtolerance="10000"
- guidetolerance="10"
- objecttolerance="10"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="24"
- inkscape:cx="25.678198"
- inkscape:cy="30.891482"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- width="48px"
- height="48px"
- inkscape:window-width="1680"
- inkscape:window-height="1000"
- inkscape:window-x="0"
- inkscape:window-y="0" />
- <metadata
- id="metadata3324">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient2286);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path2237"
- sodipodi:cx="25.573694"
- sodipodi:cy="38.689762"
- sodipodi:rx="20.977501"
- sodipodi:ry="3.0641294"
- d="M 46.551195 38.689762 A 20.977501 3.0641294 0 1 1 4.5961933,38.689762 A 20.977501 3.0641294 0 1 1 46.551195 38.689762 z"
- transform="translate(-1.4676415,0.7071068)" />
- <path
- style="fill:url(#linearGradient2283);fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
- d="M 3.7597844,35.215108 C 3.7592897,35.220202 3.7600001,35.337867 3.7597844,35.340108 L 3.7597844,35.371358 C 3.7597103,35.372133 3.7597844,35.433858 3.7597844,35.433858 L 3.7910344,35.433858 L 5.2285344,38.871358 C 11.911415,39.872542 18.429899,40.145888 24.041035,40.090108 C 24.111553,40.089409 24.189559,40.090913 24.259785,40.090108 C 29.870922,40.145891 36.389405,39.87254 43.072285,38.871358 L 44.509785,35.433858 L 44.541035,35.433858 C 44.541034,35.43386 44.541109,35.372131 44.541035,35.371358 L 44.541035,35.340108 C 44.540819,35.337867 44.54153,35.220202 44.541035,35.215108 L 3.7597844,35.215108 z "
- id="path3378" />
- <path
- style="fill:url(#linearGradient2280);fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
- d="M 22.07987,5.0113468 C 17.153472,5.1087058 12.536218,5.9642818 9.5798698,8.2300955 C 6.090401,11.046588 3.7593887,34.730192 3.7048693,35.292596 L 44.48612,35.292596 C 44.431602,34.730192 42.100588,11.046588 38.61112,8.2300955 C 35.654773,5.9642808 31.037517,5.1087058 26.11112,5.0113468 C 25.485073,4.9989748 24.841291,5.0010938 24.20487,5.0113468 C 24.132068,5.0098478 24.059152,5.0125238 23.98612,5.0113468 C 23.349699,5.0010928 22.705916,4.9989748 22.07987,5.0113468 z "
- id="path3395" />
- <path
- style="fill:#eeeeee;fill-opacity:0.92655364;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
- d="M 22.155713,5.3748772 C 17.350116,5.4708299 12.846082,6.3140491 9.9622258,8.5471361 C 6.5583227,11.322947 4.2539863,34.664469 4.2008038,35.21875 L 4.4141898,35.21875 C 4.7293798,32.10335 6.8404066,12.189785 10.023194,9.5942895 C 12.907049,7.3612026 17.411083,6.5179834 22.21668,6.4220306 C 22.827375,6.4098373 23.424888,6.4119247 24.045703,6.4220306 C 24.116945,6.4231906 24.218556,6.4205533 24.289573,6.4220306 C 24.910388,6.4119257 25.5079,6.4098373 26.118596,6.4220306 C 30.924193,6.5179834 35.428229,7.3612016 38.312083,9.5942895 C 41.49487,12.189785 43.605898,32.103352 43.921087,35.21875 L 43.982054,35.21875 C 43.928873,34.66447 41.655018,11.322947 38.251115,8.5471361 C 35.367261,6.3140482 30.863225,5.4708299 26.057629,5.3748772 C 25.446933,5.3626839 24.849421,5.3647723 24.228606,5.3748772 C 24.157589,5.3733998 24.055977,5.3760372 23.984736,5.3748772 C 23.363921,5.3647713 22.766408,5.3626839 22.155713,5.3748772 z "
- id="path3476" />
- <path
- style="fill:#5f5f5f;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
- d="M 43.856735,35.394922 L 42.566993,38.180445 C 35.999987,39.072866 29.594528,39.316522 24.080682,39.266799 C 24.011674,39.267517 23.93502,39.266176 23.865724,39.266799 C 18.351879,39.31652 11.94642,39.072868 5.379413,38.180445 L 4.1203784,35.450633 C 4.1204658,35.47767 4.1204845,35.505345 4.1203784,35.506344 L 4.1203784,35.534198 C 4.1203055,35.534889 4.1203784,35.589909 4.1203784,35.589909 L 4.1510866,35.589909 L 5.5636619,38.653984 C 12.130669,39.546407 18.536128,39.790059 24.049973,39.740338 C 24.119269,39.739715 24.195922,39.741056 24.264931,39.740338 C 29.778777,39.790061 36.184236,39.546405 42.751242,38.653984 L 44.163817,35.589909 L 44.194525,35.589909 C 44.194524,35.589911 44.194598,35.534888 44.194525,35.534198 L 44.194525,35.506344 C 44.194314,35.504346 44.195012,35.399463 44.194525,35.394922 L 43.856735,35.394922 z "
- id="path3483" />
- <path
- style="fill:none;fill-opacity:1;stroke:url(#linearGradient2275);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
- d="M 22.090428,5.0211771 C 17.164031,5.1185361 12.546776,5.9741125 9.5904278,8.2399275 C 6.0803209,11.073079 3.7431507,35.108148 3.7154276,35.396178 L 3.7154276,35.427428 C 3.7153535,35.4282 3.7154276,35.489928 3.7154276,35.489928 L 3.7466776,35.489928 L 5.1841776,38.927428 C 11.867058,39.92861 18.385542,40.201957 23.996678,40.146178 C 24.067195,40.145476 24.145202,40.146983 24.215428,40.146178 C 29.826564,40.201957 36.345048,39.92861 43.027928,38.927428 L 44.465428,35.489928 L 44.496678,35.489928 C 44.496678,35.489928 44.496752,35.4282 44.496678,35.427428 L 44.496678,35.396178 C 44.468955,35.108148 42.131785,11.073079 38.621678,8.2399275 C 35.66533,5.9741126 31.048075,5.1185362 26.121678,5.0211771 C 25.495632,5.0088047 24.851849,5.0109237 24.215428,5.0211771 C 24.142627,5.019678 24.06971,5.0223537 23.996678,5.0211771 C 23.360258,5.0109236 22.716474,5.0088047 22.090428,5.0211771 z "
- id="rect3335" />
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient2292);fill-opacity:1;stroke:url(#linearGradient2294);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path3494"
- sodipodi:cx="24.833334"
- sodipodi:cy="18.833334"
- sodipodi:rx="12.5"
- sodipodi:ry="12.5"
- d="M 37.333334 18.833334 A 12.5 12.5 0 1 1 12.333334,18.833334 A 12.5 12.5 0 1 1 37.333334 18.833334 z"
- transform="matrix(0.9615385,0,0,0.9615385,0.2278461,2.8076925)" />
- <rect
- style="fill:url(#linearGradient2299);fill-opacity:1;stroke:#535353;stroke-width:0.48494926;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect3512"
- width="4.1886005"
- height="12.75308"
- x="22.011753"
- y="14.540128" />
- </g>
-</svg>
diff --git a/timer-applet/src/Makefile.am b/timer-applet/src/Makefile.am
deleted file mode 100644
index d266f640..00000000
--- a/timer-applet/src/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-SUBDIRS = timerapplet
-
-libexec_SCRIPTS = timer-applet
-
-EXTRA_DIST = \
- timer-applet
diff --git a/timer-applet/src/timer-applet b/timer-applet/src/timer-applet
deleted file mode 100755
index cd550fbb..00000000
--- a/timer-applet/src/timer-applet
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-from os import path
-import gettext
-import locale
-import sys
-import gtk
-import mateapplet
-from timerapplet import config
-from timerapplet.controllers import GlobalController, TimerApplet, TimerService, TimerManagerService
-from timerapplet.core import AppletMateConfWrapper, Timer
-
-from dbus.mainloop.glib import DBusGMainLoop
-DBusGMainLoop(set_as_default=True)
-
-DBUS_BUS_NAME = 'net.launchpad.timerapplet.TimerApplet'
-DBUS_OBJ_NAMESPACE = '/net/launchpad/timerapplet/TimerApplet'
-
-gettext.bindtextdomain(config.GETTEXT_PACKAGE, config.LOCALE_DIR)
-gettext.bind_textdomain_codeset(config.GETTEXT_PACKAGE, 'UTF-8')
-gettext.textdomain(config.GETTEXT_PACKAGE)
-locale.bindtextdomain(config.GETTEXT_PACKAGE, config.LOCALE_DIR)
-locale.bind_textdomain_codeset(config.GETTEXT_PACKAGE, 'UTF-8')
-locale.textdomain(config.GETTEXT_PACKAGE)
-
-global_controller = GlobalController()
-timer_manager_obj_path = path.join(DBUS_OBJ_NAMESPACE, 'TimerManager')
-print 'Timer Manager D-Bus object path: %s' % timer_manager_obj_path
-
-timer_manager = None
-try:
- timer_manager = TimerManagerService(DBUS_BUS_NAME, timer_manager_obj_path)
-except Exception, err:
- print 'ERROR: Could not start TimerManagerService. D-Bus support will not be available. Error message: %s' % err
-
-def check_dependencies():
- # Check for optional dependencies
- try:
- import dbus # >= 0.80
- except ImportError, err:
- print 'Missing optional dependency: %s' % err
-
- # Check for required dependencies
- try:
- import gobject # >= 2.12
- import gtk # >= 2.10, includes pango
- import gtk.glade # >= 2.10
- import mateconf # >= 2.18
- import mate # >= 2.18, includes matecomponent.ui
- import mateapplet # >= 2.18, included in python-mate2-desktop
- import pynotify # >= 0.1.1
- except ImportError, err:
- dialog = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
- buttons=gtk.BUTTONS_CLOSE,
- message_format='%s\n\nPlease install required dependencies.' % err)
- dialog.run()
- dialog.destroy()
- sys.exit(1)
-
-def get_timer_id(mateconf_wrapper):
- path_components = mateconf_wrapper.get_base_path().split('/')
-
- # Use the second component from the end, which should usually be 'applet_*',
- # where '*' is some integer assigned by the system.
- # It could also be 'timer-applet' if we're running in standalone mode.
- # D-Bus doesn't like hyphens in object paths, so we have to replace them
- # with underscores.
- return path_components[-2].replace('-', '_')
-
-def applet_factory(applet, iid):
- check_dependencies()
-
- timer = Timer()
- mateconf_wrapper = AppletMateConfWrapper(applet,
- '/schemas/apps/timer-applet/prefs',
- '/apps/timer-applet/prefs')
- timer_id = get_timer_id(mateconf_wrapper)
- print 'Timer ID: %s' % timer_id
-
- if timer_manager is not None:
- timer_manager.register_timer_id(timer_id)
- applet.connect('destroy', lambda sender: timer_manager.unregister_timer_id(timer_id))
-
- TimerApplet(global_controller.get_presets_store(),
- global_controller.get_manage_presets_dialog(),
- applet,
- timer,
- mateconf_wrapper)
-
- timer_obj_path = path.join(DBUS_OBJ_NAMESPACE, 'Timers', timer_id)
- print 'Timer D-Bus object path: %s' % timer_obj_path
-
- try:
- TimerService(DBUS_BUS_NAME, timer_obj_path, timer)
- except Exception, err:
- print 'ERROR: Could not start TimerService. D-Bus support will not be available. Error message: %s' % err
-
- return True
-
-if __name__ == '__main__':
- windowed_mode = (len(sys.argv) > 1 and sys.argv[1] == '-w')
-
- if windowed_mode:
- win = gtk.Window()
- win.set_title('Timer Applet')
- applet = mateapplet.Applet()
- applet_factory(applet, None)
- applet.reparent(win)
-
- applet.connect('destroy', gtk.main_quit)
- win.show()
-
- gtk.main()
- else:
- mateapplet.matecomponent_factory(
- 'OAFIID:TimerApplet_Factory',
- mateapplet.Applet.__gtype__,
- config.PACKAGE,
- config.VERSION,
- applet_factory)
diff --git a/timer-applet/src/timerapplet/Makefile.am b/timer-applet/src/timerapplet/Makefile.am
deleted file mode 100644
index 08f474c0..00000000
--- a/timer-applet/src/timerapplet/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-SUBDIRS = controllers core ui
-
-defs.py: defs.py.in Makefile
- sed -e "s|\@PACKAGE\@|$(PACKAGE)|" \
- -e "s|\@VERSION\@|$(VERSION)|" \
- -e "s|\@RESOURCESDIR\@|$(pkgdatadir)|" \
- -e "s|\@IMAGESDIR\@|$(datadir)/pixmaps|" \
- -e "s|\@LOCALEDIR\@|$(localedir)|" \
- -e "s|\@GETTEXT_PACKAGE\@|$(GETTEXT_PACKAGE)|" $< > $@
-
-EXTRA_DIST = \
- defs.py.in
-
-CLEANFILES = \
- defs.py
-
-# Need this so that defs.py is actually created after cleaning.
-BUILT_SOURCES = defs.py
-
-moduledir = $(pythondir)/timerapplet
-module_PYTHON = \
- __init__.py \
- config.py \
- defs.py \
- utils.py \
- logger.py
-
diff --git a/timer-applet/src/timerapplet/__init__.py b/timer-applet/src/timerapplet/__init__.py
deleted file mode 100644
index 8b137891..00000000
--- a/timer-applet/src/timerapplet/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/timer-applet/src/timerapplet/config.py b/timer-applet/src/timerapplet/config.py
deleted file mode 100644
index 42376845..00000000
--- a/timer-applet/src/timerapplet/config.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os.path as path
-
-try:
- from defs import *
-except ImportError:
- PACKAGE = 'timer-applet'
- VERSION = '0'
- GETTEXT_PACKAGE = ''
- LOCALE_DIR = ''
- RESOURCES_DIR = path.join(path.dirname(__file__), '../../data')
- IMAGES_DIR = path.join(path.dirname(__file__), '../../images')
-
-print 'Using these definitions:'
-print 'GETTEXT_PACKAGE: %s' % GETTEXT_PACKAGE
-print 'LOCALE_DIR: %s' % LOCALE_DIR
-print 'RESOURCES_DIR: %s' % RESOURCES_DIR
-print 'IMAGES_DIR: %s' % IMAGES_DIR
-
-GLADE_PATH = path.join(RESOURCES_DIR, 'timer-applet.glade')
-POPUP_MENU_FILE_PATH = path.join(RESOURCES_DIR, 'TimerApplet.xml')
-ICON_PATH = path.join(IMAGES_DIR, 'timer-applet.png')
-PRESETS_PATH = path.expanduser('~/.config/mate/timer-applet/presets.xml')
-DEFAULT_SOUND_PATH = '/usr/share/sounds/gtk-events/clicked.wav'
diff --git a/timer-applet/src/timerapplet/controllers/GlobalController.py b/timer-applet/src/timerapplet/controllers/GlobalController.py
deleted file mode 100644
index fd3af2b1..00000000
--- a/timer-applet/src/timerapplet/controllers/GlobalController.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from gettext import gettext as _
-import gtk
-from timerapplet import core
-from timerapplet import ui
-from timerapplet import utils
-from timerapplet import config
-
-class GlobalController(object):
- def __init__(self):
- self._presets_store = core.PresetsStore(config.PRESETS_PATH)
- self._manage_presets_dialog = ui.ManagePresetsDialog(config.GLADE_PATH,
- self._presets_store.get_model(),
- lambda row_iter: utils.get_preset_display_text(self._presets_store,
- row_iter))
-
- self._manage_presets_dialog.connect('clicked-add', self._on_mgr_clicked_add)
- self._manage_presets_dialog.connect('clicked-edit', self._on_mgr_clicked_edit)
- self._manage_presets_dialog.connect('clicked-remove', self._on_mgr_clicked_remove)
-
- gtk.window_set_default_icon_from_file(config.ICON_PATH)
-
- def get_presets_store(self):
- return self._presets_store
-
- def get_manage_presets_dialog(self):
- return self._manage_presets_dialog
-
- def _on_mgr_clicked_add(self, sender, data=None):
- add_dialog = ui.AddEditPresetDialog(
- config.GLADE_PATH,
- _('Add Preset'),
- lambda name: utils.is_valid_preset_name(name, self._presets_store))
-
- result = add_dialog.get_preset()
- if result is not None:
- (name, hours, minutes, seconds, command, next_timer, auto_start) = result
- self._presets_store.add_preset(name, hours, minutes, seconds,
- command, next_timer, auto_start)
-
- def _on_mgr_clicked_edit(self, sender, row_path, data=None):
- row_iter = self._presets_store.get_model().get_iter(row_path)
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- self._presets_store.get_preset(row_iter)
-
- edit_dialog = ui.AddEditPresetDialog(config.GLADE_PATH,
- _('Edit Preset'),
- lambda name: utils.is_valid_preset_name(name,
- self._presets_store,
- (name,)),
- name,
- hours,
- minutes,
- seconds,
- command,
- next_timer,
- auto_start
- )
-
- result = edit_dialog.get_preset()
- if result is not None:
- (name, hours, minutes, seconds, command, next_timer, auto_start) = result
- self._presets_store.modify_preset(row_iter, name, hours, minutes,
- seconds, command, next_timer,
- auto_start)
-
- def _on_mgr_clicked_remove(self, sender, row_path, data=None):
- row_iter = self._presets_store.get_model().get_iter(row_path)
- self._presets_store.remove_preset(row_iter)
-
- # TODO
- def _on_mgr_next_timer_is_being_edited(self, sender, row_path, data=None):
- """Show a dropdown widget to help completing the next timer."""
- raise NotImplementedError("Not implemented, yet")
-
-
diff --git a/timer-applet/src/timerapplet/controllers/Makefile.am b/timer-applet/src/timerapplet/controllers/Makefile.am
deleted file mode 100644
index bb5018d6..00000000
--- a/timer-applet/src/timerapplet/controllers/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-moduledir = $(pythondir)/timerapplet/controllers
-module_PYTHON = \
- __init__.py \
- GlobalController.py \
- TimerApplet.py \
- TimerManagerService.py \
- TimerService.py
-
diff --git a/timer-applet/src/timerapplet/controllers/TimerApplet.py b/timer-applet/src/timerapplet/controllers/TimerApplet.py
deleted file mode 100644
index 2771038c..00000000
--- a/timer-applet/src/timerapplet/controllers/TimerApplet.py
+++ /dev/null
@@ -1,637 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from gettext import gettext as _
-from gettext import ngettext
-from datetime import datetime, timedelta
-import mateapplet
-import gst
-import gtk
-import gtk.glade as glade
-import gtk.gdk as gdk
-import subprocess
-import shlex
-import threading
-from timerapplet import config
-from timerapplet import core
-from timerapplet import ui
-from timerapplet import utils
-
-def on_widget_button_press_event(sender, event, data=None):
- if event.button != 1:
- sender.emit_stop_by_name('button-press-event')
- return False
-
-def force_no_focus_padding(widget):
- gtk.rc_parse_string('\n'
- ' style "timer-applet-button-style"\n'
- ' {\n'
- ' GtkWidget::focus-line-width=0\n'
- ' GtkWidget::focus-padding=0\n'
- ' }\n'
- '\n'
- ' widget "*.timer-applet-button" style "timer-applet-button-style"\n'
- '\n')
- widget.set_name('timer-applet-button')
-
-class TimerApplet(object):
- # MateConf key identifiers
- ## You can find Timer Applet's schemas file in data/timer-applet.schemas.in
- _SHOW_REMAINING_TIME_KEY = 'show_remaining_time'
- _PLAY_SOUND_KEY = 'play_notification_sound'
- _USE_CUSTOM_SOUND_KEY = 'use_custom_notification_sound'
- _SHOW_POPUP_NOTIFICATION_KEY = 'show_popup_notification'
- _SHOW_PULSING_ICON_KEY = 'show_pulsing_icon'
- _CUSTOM_SOUND_PATH_KEY = 'custom_notification_sound_path'
-
- _PRESETS_PLACEHOLDER_NAME = 'Placeholder'
- _PRESETS_PLACEHOLDER_PATH = '/popups/popup/Presets/' + _PRESETS_PLACEHOLDER_NAME
- _PRESETS_PATH = '/popups/popup/Presets'
-
- def __init__(self, presets_store, manage_presets_dialog, applet, timer, mateconf_wrapper):
- self._presets_store = presets_store
- self._manage_presets_dialog = manage_presets_dialog
- self._applet = applet
- self._timer = timer
-
- self._gst_playbin = gst.element_factory_make('playbin', 'player')
- def bus_event(bus, message):
- t = message.type
- if t == gst.MESSAGE_EOS:
- self._gst_playbin.set_state(gst.STATE_NULL)
- elif t == gst.MESSAGE_ERROR:
- self._gst_playbin.set_state(gst.STATE_NULL)
- err, debug = message.parse_error()
- print 'Error playing sound: %s' % err, debug
- return True
- self._gst_playbin.get_bus().add_watch(bus_event)
-
- self._status_button = ui.StatusButton()
- self._notifier = ui.Notifier('TimerApplet', gtk.STOCK_DIALOG_INFO, self._status_button)
- self._start_next_timer_dialog = ui.StartNextTimerDialog(
- config.GLADE_PATH,
- "Start next timer",
- "Would you like to start the next timer?")
- self._start_timer_dialog = ui.StartTimerDialog(config.GLADE_PATH,
- lambda name: utils.is_valid_preset_name(name,
- self._presets_store),
- self._presets_store.get_model(),
- lambda row_iter: utils.get_preset_display_text(self._presets_store,
- row_iter))
- self._continue_dialog = ui.ContinueTimerDialog(config.GLADE_PATH,
- _('Continue timer countdown?'),
- _('The timer is currently paused. Would you like to continue countdown?'))
- self._preferences_dialog = ui.PreferencesDialog(config.GLADE_PATH)
- self._mateconf = mateconf_wrapper
-
- self._about_dialog = glade.XML(config.GLADE_PATH, 'about_dialog').get_widget('about_dialog')
- self._about_dialog.set_version(config.VERSION)
-
- self._applet.set_applet_flags(mateapplet.EXPAND_MINOR)
- self._applet.setup_menu_from_file(
- None,
- config.POPUP_MENU_FILE_PATH,
- None,
- [('PauseTimer', lambda component, verb: self._timer.stop()),
- ('ContinueTimer', lambda component, verb: self._timer.start()),
- ('StopTimer', lambda component, verb: self._timer.reset()),
- ('RestartTimer', lambda component, verb: self._restart_timer()),
- ('StartNextTimer', lambda component, verb: self._start_next_timer()),
- ('ManagePresets', lambda component, verb: self._manage_presets_dialog.show()),
- ('Preferences', lambda component,
- verb: self._preferences_dialog.show()),
- ('About', lambda component, verb: self._about_dialog.show())]
- )
- self._applet.add(self._status_button)
-
- # Remove padding around button contents.
- force_no_focus_padding(self._status_button)
-
- # TODO:
- # Fix bug in which button would not propogate middle-clicks
- # and right-clicks to the applet.
- self._status_button.connect('button-press-event', on_widget_button_press_event)
-
- self._status_button.set_relief(gtk.RELIEF_NONE)
- self._status_button.set_icon(config.ICON_PATH);
-
- self._applet.set_tooltip_text(_("Timer Applet"))
-
- self._connect_signals()
- self._update_status_button()
- self._update_popup_menu()
- self._update_preferences_dialog()
- self._status_button.show()
- self._applet.show()
-
- def _connect_signals(self):
- self._applet.connect('change-orient', lambda applet, orientation: self._update_status_button())
- self._applet.connect('change-size', lambda applet, size: self._update_status_button())
- self._applet.connect('change-background', self._on_applet_change_background)
- self._applet.connect('destroy', self._on_applet_destroy)
-
- self._presets_store.get_model().connect('row-deleted',
- lambda model,
- row_path: self._update_popup_menu())
- self._presets_store.get_model().connect('row-changed',
- lambda model,
- row_path,
- row_iter: self._update_popup_menu())
-
- self._timer.connect('time-changed', self._on_timer_time_changed)
- self._timer.connect('state-changed', self._on_timer_state_changed)
- self._status_button.connect('clicked', self._on_status_button_clicked)
- self._start_timer_dialog.connect('clicked-start',
- self._on_start_dialog_clicked_start)
- self._start_timer_dialog.connect('clicked-manage-presets',
- self._on_start_dialog_clicked_manage_presets)
- self._start_timer_dialog.connect('clicked-save',
- self._on_start_dialog_clicked_save)
- self._start_timer_dialog.connect('clicked-preset',
- self._on_start_dialog_clicked_preset)
- self._start_timer_dialog.connect('double-clicked-preset',
- self._on_start_dialog_double_clicked_preset)
-
- self._preferences_dialog.connect('show-remaining-time-changed', self._on_prefs_show_time_changed)
- self._preferences_dialog.connect('play-sound-changed', self._on_prefs_play_sound_changed)
- self._preferences_dialog.connect('use-custom-sound-changed', self._on_prefs_use_custom_sound_changed)
- self._preferences_dialog.connect('show-popup-notification-changed', self._on_prefs_show_popup_notification_changed)
- self._preferences_dialog.connect('show-pulsing-icon-changed', self._on_prefs_show_pulsing_icon_changed)
- self._preferences_dialog.connect('custom-sound-path-changed', self._on_prefs_custom_sound_path_changed)
-
- self._about_dialog.connect('delete-event', gtk.Widget.hide_on_delete)
- self._about_dialog.connect('response', lambda dialog, response_id: self._about_dialog.hide())
-
- self._mateconf.add_notification(TimerApplet._SHOW_REMAINING_TIME_KEY, self._on_mateconf_changed)
- self._mateconf.add_notification(TimerApplet._PLAY_SOUND_KEY, self._on_mateconf_changed)
- self._mateconf.add_notification(TimerApplet._USE_CUSTOM_SOUND_KEY, self._on_mateconf_changed)
- self._mateconf.add_notification(TimerApplet._SHOW_PULSING_ICON_KEY, self._on_mateconf_changed)
- self._mateconf.add_notification(TimerApplet._SHOW_POPUP_NOTIFICATION_KEY, self._on_mateconf_changed)
- self._mateconf.add_notification(TimerApplet._CUSTOM_SOUND_PATH_KEY, self._on_mateconf_changed)
-
- ## Private methods for updating UI ##
-
- def _update_status_button(self):
- current_state = self._timer.get_state()
- if current_state == core.Timer.STATE_IDLE:
- print 'Idle'
- # This label text should not be visible because the label
- # is hidden when the timer is idle.
- self._status_button.set_label('--:--:--')
- self._status_button.set_tooltip(_('Click to start a new timer countdown.'))
- elif current_state == core.Timer.STATE_RUNNING:
- print 'Running'
- elif current_state == core.Timer.STATE_PAUSED:
- print 'Paused'
- self._status_button.set_tooltip(_('Paused. Click to continue timer countdown.'))
- elif current_state == core.Timer.STATE_FINISHED:
- print 'Finished'
- self._status_button.set_label(_('Finished'))
- name_str = self._timer.get_name()
- time_str = utils.get_display_text_from_datetime(self._timer.get_end_time())
- if len(name_str) > 0:
- # "<timer name>" finished at <time>
- self._status_button.set_tooltip(_('"%s" finished at %s.\nClick to stop timer.') % (name_str, time_str))
- else:
- # Timer finished at <time>
- self._status_button.set_tooltip(_('Timer finished at %s.\nClick to stop timer.') % time_str)
-
- self._status_button.set_sensitized(current_state == core.Timer.STATE_RUNNING or
- current_state == core.Timer.STATE_FINISHED)
- self._status_button.set_use_icon(current_state == core.Timer.STATE_IDLE)
- self._status_button.set_show_remaining_time(current_state != core.Timer.STATE_IDLE and
- self._mateconf.get_bool(TimerApplet._SHOW_REMAINING_TIME_KEY))
-
- if current_state == core.Timer.STATE_PAUSED:
- self._status_button.set_pie_fill_color(0.4, 0.4, 0.4)
- else:
- # Use theme color
- color = self._applet.style.base[gtk.STATE_SELECTED]
- red = color.red / 65535.0
- green = color.green / 65535.0
- blue = color.blue / 65535.0
- self._status_button.set_pie_fill_color(red, green, blue)
-
- orientation = self._applet.get_orient()
- size = self._applet.get_size()
- use_vertical = (orientation == mateapplet.ORIENT_LEFT or
- orientation == mateapplet.ORIENT_RIGHT or
- size >= mateapplet.SIZE_MEDIUM)
- self._status_button.set_use_vertical_layout(use_vertical)
-
- def _update_popup_menu(self):
- popup = self._applet.get_popup_component()
-
- timer_state = self._timer.get_state()
- has_next_timer = self._timer.get_next_timer()
- show_pause = (timer_state == core.Timer.STATE_RUNNING)
- show_continue = (timer_state == core.Timer.STATE_PAUSED)
- show_stop = (timer_state == core.Timer.STATE_RUNNING or
- timer_state == core.Timer.STATE_PAUSED or
- timer_state == core.Timer.STATE_FINISHED)
- show_restart = (timer_state == core.Timer.STATE_RUNNING or
- timer_state == core.Timer.STATE_PAUSED or
- timer_state == core.Timer.STATE_FINISHED)
- show_next_timer = ((timer_state == core.Timer.STATE_RUNNING or
- timer_state == core.Timer.STATE_PAUSED or
- timer_state == core.Timer.STATE_FINISHED) and
- # Only show this popup menu item if it has a
- # next_timer defined. Clever, huh? ;)
- has_next_timer)
-
- show_presets_menu = (len(self._presets_store.get_model()) > 0)
- show_separator = (
- show_presets_menu or
- show_pause or
- show_next_timer or
- show_continue or
- show_stop or
- show_restart)
-
- to_hidden_str = lambda show: ('0', '1')[not show]
- popup.set_prop('/commands/PauseTimer', 'hidden', to_hidden_str(show_pause))
- popup.set_prop('/commands/ContinueTimer', 'hidden', to_hidden_str(show_continue))
- popup.set_prop('/commands/StopTimer', 'hidden', to_hidden_str(show_stop))
- popup.set_prop('/commands/RestartTimer', 'hidden', to_hidden_str(show_restart))
- popup.set_prop('/commands/StartNextTimer', 'hidden', to_hidden_str(show_next_timer))
- popup.set_prop(TimerApplet._PRESETS_PATH, 'hidden', to_hidden_str(show_presets_menu))
- popup.set_prop('/popups/popup/Separator1', 'hidden', to_hidden_str(show_separator))
-
- # Rebuild the Presets submenu
- if popup.path_exists(TimerApplet._PRESETS_PLACEHOLDER_PATH):
- popup.rm(TimerApplet._PRESETS_PLACEHOLDER_PATH)
- popup.set_translate(TimerApplet._PRESETS_PATH,
- '<placeholder name="%s"/>' % TimerApplet._PRESETS_PLACEHOLDER_NAME)
-
- preset_number = 1
- row_iter = self._presets_store.get_model().get_iter_first()
- while row_iter is not None:
- verb = ('Preset_%d' % preset_number)
- preset_number += 1
- display_text = utils.get_preset_display_text(self._presets_store, row_iter)
- node_xml = '<menuitem verb="%s" name="%s" label="%s"/>' % (verb, verb, display_text)
- popup.set_translate(TimerApplet._PRESETS_PLACEHOLDER_PATH, node_xml)
- popup.add_verb(verb,
- self._on_presets_submenu_item_activated,
- self._presets_store.get_model().get_path(row_iter))
- row_iter = self._presets_store.get_model().iter_next(row_iter)
-
- def _update_preferences_dialog(self):
- self._preferences_dialog.props.show_remaining_time = \
- self._mateconf.get_bool(TimerApplet._SHOW_REMAINING_TIME_KEY)
- self._preferences_dialog.props.play_sound = \
- self._mateconf.get_bool(TimerApplet._PLAY_SOUND_KEY)
- self._preferences_dialog.props.use_custom_sound = \
- self._mateconf.get_bool(TimerApplet._USE_CUSTOM_SOUND_KEY)
- self._preferences_dialog.props.show_popup_notification = \
- self._mateconf.get_bool(TimerApplet._SHOW_POPUP_NOTIFICATION_KEY)
- self._preferences_dialog.props.show_pulsing_icon = \
- self._mateconf.get_bool(TimerApplet._SHOW_PULSING_ICON_KEY)
- self._preferences_dialog.props.custom_sound_path = \
- self._mateconf.get_string(TimerApplet._CUSTOM_SOUND_PATH_KEY)
-
- ## Applet callbacks ##
-
- def _on_applet_change_background(self, applet, background_type, color, pixmap):
- applet.set_style(None)
- rc_style = gtk.RcStyle()
- applet.modify_style(rc_style)
-
- if background_type == mateapplet.NO_BACKGROUND:
- pass
- elif background_type == mateapplet.COLOR_BACKGROUND:
- applet.modify_bg(gtk.STATE_NORMAL, color)
- elif background_type == mateapplet.PIXMAP_BACKGROUND:
- style = applet.style.copy()
- style.bg_pixmap[gtk.STATE_NORMAL] = pixmap
- applet.set_style(style)
-
- def _on_applet_destroy(self, sender, data=None):
- self._call_notify(show=False)
- if self._timer.get_state() != core.Timer.STATE_IDLE:
- self._timer.reset() # will stop timeout
- self._mateconf.delete()
-
- ## Popup menu callbacks ##
-
- def _on_presets_submenu_item_activated(self, component, verb, row_path):
- # Try hiding the Start Timer dialog, just in case it's open.
- self._start_timer_dialog.hide()
- row_iter = self._presets_store.get_model().get_iter(row_path)
- (name, hours, minutes, seconds, command, next_timer, auto_start) = self._presets_store.get_preset(row_iter)
- self._start_timer_with_settings(name, hours, minutes, seconds, command,
- next_timer, auto_start)
-
- ## MateConf callbacks ##
-
- def _on_mateconf_changed(self, mateconf_value, data=None):
- self._update_status_button()
- self._update_preferences_dialog()
-
- ## PreferencesDialog callbacks ##
-
- def _on_prefs_show_time_changed(self, sender, show_time):
- self._mateconf.set_bool(TimerApplet._SHOW_REMAINING_TIME_KEY,
- show_time)
-
- def _on_prefs_play_sound_changed(self, sender, play_sound):
- self._mateconf.set_bool(TimerApplet._PLAY_SOUND_KEY,
- play_sound)
-
- def _on_prefs_use_custom_sound_changed(self, sender, use_custom_sound):
- self._mateconf.set_bool(TimerApplet._USE_CUSTOM_SOUND_KEY,
- use_custom_sound)
-
- def _on_prefs_show_pulsing_icon_changed(self, sender, show_pulsing_icon):
- self._mateconf.set_bool(TimerApplet._SHOW_PULSING_ICON_KEY,
- show_pulsing_icon)
-
- def _on_prefs_show_popup_notification_changed(self, sender,
- show_popup_notification):
- self._mateconf.set_bool(TimerApplet._SHOW_POPUP_NOTIFICATION_KEY,
- show_popup_notification)
-
- def _on_prefs_custom_sound_path_changed(self, sender, custom_sound_path):
- self._mateconf.set_string(TimerApplet._CUSTOM_SOUND_PATH_KEY,
- custom_sound_path)
-
- ## Timer callbacks ##
-
- def _on_timer_time_changed(self, timer):
- hours, minutes, seconds = utils.seconds_to_hms(timer.get_remaining_time())
- print 'Remaining time: %d, %d, %d' % (hours, minutes, seconds)
- name = self._timer.get_name()
- self._status_button.set_label(utils.construct_time_str(self._timer.get_remaining_time(),
- show_all=False))
-
- fraction_remaining = float(self._timer.get_remaining_time()) / self._timer.get_duration()
- progress = min(1.0, max(0.0, 1.0 - fraction_remaining))
- self._status_button.set_progress(progress)
-
- if len(name) > 0:
- # HH:MM:SS (<timer name>)
- self._status_button.set_tooltip(_('%02d:%02d:%02d (%s)') % (hours, minutes, seconds, name))
- else:
- # HH:MM:SS
- self._status_button.set_tooltip(_('%02d:%02d:%02d') % (hours, minutes, seconds))
-
- def _on_timer_state_changed(self, timer, data=None):
- # TODO:
- # Refactor me!
- print 'State changed'
- new_state = timer.get_state()
- print ' new state: %d' % new_state
-
- # These actions should be done once upon a state change.
- # That's why they're done here and not in self._update_status_button();
- # self._update_status_button() could be called multiple times
- # while in the same state.
- if new_state == core.Timer.STATE_FINISHED:
- name = self._timer.get_name()
- command = self._timer.get_command()
- end_time = self._timer.get_end_time()
- time_text = utils.get_display_text_from_datetime(end_time)
- summary = None
- message = None
- if len(name) > 0:
- # "<timer name>" Finished
- summary = (_('"%s" Finished') % name)
-
- # "<timer name>" finished at <time>
- message = (_('"%s" finished at %s') % (name, time_text))
- else:
- summary = _('Timer Finished')
-
- # Timer finished at <time>
- message = (_('Timer finished at %s') % time_text)
-
-
- def reminder_message_func():
- elapsed_time = datetime.now() - end_time
- message = None
- if elapsed_time < timedelta(seconds=60):
- message = ngettext('Timer finished about <b>%d second</b> ago',
- 'Timer finished about <b>%d seconds</b> ago',
- elapsed_time.seconds) % elapsed_time.seconds
- else:
- minutes = elapsed_time.seconds / 60
- message = ngettext('Timer finished about <b>%d minute</b> ago',
- 'Timer finished about <b>%d minutes</b> ago',
- minutes) % minutes
- return message
-
- # TODO:
- # FIXME:
- # Reason for using a Python thread:
- # To do all the procedures after timer has ended. If I don't do
- # this then after the timer ended and it had an auto-start and next
- # timer defined, it would directly switch without any notification.
- # Trying time.sleep() doesn't work as expected; it correctly starts
- # the next timer, but it doesn't show the notification and the
- # rest.
- class MyThread(threading.Thread):
- def __init__(self, timer_instance):
- threading.Thread.__init__(self)
- self.timer = timer_instance
-
- def run(self):
- print "Starting thread..."
- print "Calling popup notification.",
- self.timer._call_notify(summary, message, reminder_message_func)
- print "Starting pulsing button.",
- self.timer._start_pulsing_button()
- print "Playing notification sound.",
- self.timer._play_notification_sound()
- print "Running custom command.",
- self.timer._run_custom_command(command)
-
- print "Ending Thread..."
- thread = MyThread(self)
- thread.start()
- thread.join()
-
- next_timer = self._timer.get_next_timer()
- auto_start = self._timer.get_auto_start()
- if auto_start and next_timer:
- # Start next timer
- self._stop_sound()
- self._call_notify(show=False)
- self._stop_pulsing_button()
- self._start_next_timer()
- elif not(auto_start) and next_timer:
- self._status_button.props.sensitive = False
- dialog_result = self._start_next_timer_dialog.get_response()
- self._status_button.props.sensitive = True
- if dialog_result:
- # Start next timer
- self._stop_sound()
- self._call_notify(show=False)
- self._stop_pulsing_button()
- self._start_next_timer()
- else:
- self._stop_sound()
- self._call_notify(show=False)
- self._stop_pulsing_button()
-
- print "Updating status button..."
- self._update_status_button()
- print "Updating popup menu..."
- self._update_popup_menu()
-
- ## StatusButton callbacks ##
-
- def _on_status_button_clicked(self, button, data=None):
- current_state = self._timer.get_state()
- if current_state == core.Timer.STATE_IDLE:
- self._start_timer_dialog.show()
- elif current_state == core.Timer.STATE_FINISHED:
- self._timer.reset()
- elif current_state == core.Timer.STATE_PAUSED:
- # Temporarily disable status button while the Continue dialog is open.
- self._status_button.props.sensitive = False
- dialog_result = self._continue_dialog.get_response()
- self._status_button.props.sensitive = True
- if dialog_result == ui.ContinueTimerDialog.CONTINUE_TIMER:
- self._timer.start()
- elif dialog_result == ui.ContinueTimerDialog.STOP_TIMER:
- self._timer.reset()
- elif dialog_result == ui.ContinueTimerDialog.KEEP_PAUSED:
- pass
- else:
- assert False
- elif current_state == core.Timer.STATE_RUNNING:
- self._timer.stop()
-
- ## StartTimerDialog callbacks ##
-
- def _on_start_dialog_clicked_start(self, sender, data=None):
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- self._start_timer_dialog.get_control_data()
- self._start_timer_with_settings(name, hours, minutes, seconds, command,
- next_timer, auto_start)
-
- def _on_start_dialog_clicked_manage_presets(self, sender, data=None):
- self._manage_presets_dialog.show()
-
- def _on_start_dialog_clicked_save(self, sender, name,
- hours, minutes, seconds, command,
- next_timer, auto_start, data=None):
- self._presets_store.add_preset(name, hours, minutes, seconds, command,
- next_timer, auto_start)
-
- def _on_start_dialog_clicked_preset(self, sender, row_path, data=None):
- row_iter = self._presets_store.get_model().get_iter(row_path)
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- self._presets_store.get_preset(row_iter)
- self._start_timer_dialog.set_name_and_duration(name, hours, minutes,
- seconds, command,
- next_timer, auto_start)
-
- def _on_start_dialog_double_clicked_preset(self, sender, row_path, data=None):
- """Preset is double-clicked. Start the selected preset, and hide the
- dialog."""
- row_iter = self._presets_store.get_model().get_iter(row_path)
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- self._presets_store.get_preset(row_iter)
- self._start_timer_with_settings(name, hours, minutes, seconds, command,
- next_timer, auto_start)
- self._start_timer_dialog.hide()
-
- ## Private methods ##
-
- def _start_timer_with_settings(self, name, hours, minutes, seconds,
- command, next_timer, auto_start):
- print "Resetting timer"
- if self._timer.get_state() != core.Timer.STATE_IDLE:
- self._timer.reset()
- self._timer.set_duration(utils.hms_to_seconds(hours, minutes, seconds))
- self._timer.set_name(name)
- self._timer.set_command(command)
- self._timer.set_next_timer(next_timer)
- self._timer.set_auto_start(auto_start)
- self._timer.start()
-
- def _restart_timer(self):
- self._timer.reset()
- self._timer.start()
-
- def _start_next_timer(self):
- """Start next timer, if defined."""
- next_timer = self._timer.get_next_timer()
- for row in self._presets_store.get_model():
- #print dir(row)
- if str(row[0]) == next_timer:
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- self._presets_store.get_preset(row.iter)
- break
- print "Starting timer with settings: ",
- print (name, hours, minutes, seconds, command, next_timer, auto_start)
- self._start_timer_with_settings(name, hours, minutes, seconds, command,
- next_timer, auto_start)
-
-
- def _play_notification_sound(self):
- if not self._mateconf.get_bool(TimerApplet._PLAY_SOUND_KEY):
- return
-
- sound_path = config.DEFAULT_SOUND_PATH
- if self._mateconf.get_bool(TimerApplet._USE_CUSTOM_SOUND_KEY):
- sound_path = self._mateconf.get_string(TimerApplet._CUSTOM_SOUND_PATH_KEY)
-
- print 'Playing notification sound: "%s"' % str(sound_path)
- self._play_sound(sound_path)
- print 'Started playing notification sound.'
-
- def _play_sound(self, file_path):
- if not file_path:
- print 'Invalid path to sound file'
- return
- self._gst_playbin.set_state(gst.STATE_NULL)
- sound_uri = 'file://' + file_path
- print 'Using GStreamer to play: ' + sound_uri
- self._gst_playbin.set_property('uri', sound_uri)
- self._gst_playbin.set_state(gst.STATE_PLAYING)
-
- def _run_custom_command(self, command):
- if command:
- print "Running custom command: " + command
- try:
- subprocess.call(shlex.split(command))
- except OSError:
- print "... failed. Command not found."
-
- def _stop_sound(self):
- self._gst_playbin.set_state(gst.STATE_NULL)
-
- def _start_pulsing_button(self):
- if self._mateconf.get_bool(TimerApplet._SHOW_PULSING_ICON_KEY):
- self._status_button.start_pulsing()
-
- def _stop_pulsing_button(self):
- self._status_button.stop_pulsing()
-
- def _show_about_dialog(self):
- self._about_dialog.run()
- self._about_dialog.hide()
-
- def _call_notify(self, summary=None, message=None,
- reminder_message_func=None, show=True):
- if self._mateconf.get_bool(TimerApplet._SHOW_POPUP_NOTIFICATION_KEY):
- if show:
- self._notifier.begin(summary, message, reminder_message_func)
- else:
- self._notifier.end()
diff --git a/timer-applet/src/timerapplet/controllers/TimerManagerService.py b/timer-applet/src/timerapplet/controllers/TimerManagerService.py
deleted file mode 100644
index b33155a8..00000000
--- a/timer-applet/src/timerapplet/controllers/TimerManagerService.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import dbus
-import dbus.service
-
-DBUS_INTERFACE_NAMESPACE = 'net.launchpad.timerapplet.TimerApplet.TimerManager'
-
-class TimerManagerService(dbus.service.Object):
- def __init__(self, bus_name, object_path):
- dbus.service.Object.__init__(self,
- dbus.service.BusName(bus_name, bus=dbus.SessionBus()),
- object_path)
- self._timer_id_list = []
-
- def create_and_register_timer_id(self):
- timer_id = str(uuid.uuid4())
- self.register_timer_id(timer_id)
- return timer_id
-
- def register_timer_id(self, timer_id):
- self._timer_id_list.append(timer_id)
-
- def unregister_timer_id(self, timer_id):
- self._timer_id_list.remove(timer_id)
-
- @dbus.service.method(dbus_interface=DBUS_INTERFACE_NAMESPACE, out_signature='as')
- def GetTimerIDList(self):
- return self._timer_id_list
diff --git a/timer-applet/src/timerapplet/controllers/TimerService.py b/timer-applet/src/timerapplet/controllers/TimerService.py
deleted file mode 100644
index a4b25b8a..00000000
--- a/timer-applet/src/timerapplet/controllers/TimerService.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import dbus
-import dbus.service
-from timerapplet import core
-from timerapplet import utils
-
-DBUS_INTERFACE_NAMESPACE = 'net.launchpad.timerapplet.TimerApplet.Timer'
-
-class TimerService(dbus.service.Object):
- def __init__(self, bus_name, object_path, timer):
- dbus.service.Object.__init__(self,
- dbus.service.BusName(bus_name, bus=dbus.SessionBus()),
- object_path)
- self._timer = timer
-
- @dbus.service.method(dbus_interface=DBUS_INTERFACE_NAMESPACE, in_signature='siii')
- def Start(self, name, hours, minutes, seconds):
- if self._timer.get_state() != core.Timer.STATE_IDLE:
- self._timer.reset()
- self._timer.set_duration(utils.hms_to_seconds(hours, minutes, seconds))
- self._timer.set_name(name)
- self._timer.start()
-
- @dbus.service.method(dbus_interface=DBUS_INTERFACE_NAMESPACE)
- def Stop(self):
- if self._timer.get_state() != core.Timer.STATE_IDLE:
- self._timer.reset()
-
- @dbus.service.method(dbus_interface=DBUS_INTERFACE_NAMESPACE)
- def PauseContinue(self):
- if self._timer.get_state() == core.Timer.STATE_RUNNING:
- self._timer.stop()
- elif self._timer.get_state() == core.Timer.STATE_PAUSED:
- self._timer.start()
diff --git a/timer-applet/src/timerapplet/controllers/__init__.py b/timer-applet/src/timerapplet/controllers/__init__.py
deleted file mode 100644
index 471dd256..00000000
--- a/timer-applet/src/timerapplet/controllers/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from GlobalController import GlobalController
-from TimerApplet import TimerApplet
-from TimerManagerService import TimerManagerService
-from TimerService import TimerService
diff --git a/timer-applet/src/timerapplet/core/AppletMateConfWrapper.py b/timer-applet/src/timerapplet/core/AppletMateConfWrapper.py
deleted file mode 100644
index 8e4cecb5..00000000
--- a/timer-applet/src/timerapplet/core/AppletMateConfWrapper.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from os import path
-import mateconf
-
-class AppletMateConfWrapper(object):
- def __init__(self, applet, schema_path, standalone_key):
- object.__init__(self)
- self._connection_ids = []
-
- self._client = mateconf.client_get_default()
-
- # Get preferences key path for the given applet instance.
- self._base_path = applet.get_preferences_key()
- if self._base_path is not None:
- # Apply the schema to the applet instance preferences key.
- applet.add_preferences(schema_path)
- else:
- # NOTE: Don't need to apply schema here because the Timer Applet schema file
- # already specifies that the schema be automatically applied to the standalone key.
-
- self._base_path = standalone_key
-
- # Applet would usually do this for us, but since we're running in standalone mode,
- # we have to do this ourselves in order to receive MateConf change notifications.
- self._client.add_dir(self._base_path, mateconf.CLIENT_PRELOAD_RECURSIVE)
-
- print 'Base prefs path = %s' % self._base_path
-
- def get_base_path(self):
- return self._base_path
-
- def add_notification(self, relative_key, callback, data=None):
- """Register for notifications of changes to the given preference key.
-
- relative_key should be relative to the applet's base preferences key path.
- callback should look like: callback(MateConfValue, data=None)
- """
- connection_id = self._client.notify_add(self._get_full_path(relative_key),
- self._notification_callback, (callback, data))
- self._connection_ids.append(connection_id)
-
- def get_string(self, relative_key):
- return self._client.get_string(self._get_full_path(relative_key))
-
- def get_bool(self, relative_key):
- return self._client.get_bool(self._get_full_path(relative_key))
-
- def set_string(self, relative_key, val):
- self._client.set_string(self._get_full_path(relative_key), val)
-
- def set_bool(self, relative_key, val):
- self._client.set_bool(self._get_full_path(relative_key), val)
-
- def delete(self):
- for connection_id in self._connection_ids:
- self._client.notify_remove(connection_id)
- self._connection_ids = []
-
- def _notification_callback(self, client, cnxn_id, entry, data=None):
- (callback, real_data) = data
-
- # mateconf_value is of type MateConfValue (mateconf.Value)
- mateconf_value = entry.get_value()
-
- # Ignore when mateconf_value is None because that
- # means that the settings are being removed
- # because the applet has been removed from
- # the panel.
- if mateconf_value != None:
- callback(mateconf_value, real_data)
-
- def _get_full_path(self, relative_key):
- return path.join(self._base_path, relative_key)
-
diff --git a/timer-applet/src/timerapplet/core/Makefile.am b/timer-applet/src/timerapplet/core/Makefile.am
deleted file mode 100644
index 6c974866..00000000
--- a/timer-applet/src/timerapplet/core/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-moduledir = $(pythondir)/timerapplet/core
-module_PYTHON = \
- __init__.py \
- AppletMateConfWrapper.py \
- PresetsStore.py \
- Timer.py
diff --git a/timer-applet/src/timerapplet/core/PresetsStore.py b/timer-applet/src/timerapplet/core/PresetsStore.py
deleted file mode 100644
index 6c9323b7..00000000
--- a/timer-applet/src/timerapplet/core/PresetsStore.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-try:
- from xml.etree import ElementTree as et
-except:
- from elementtree import ElementTree as et
-
-import os
-from os import path
-import gobject
-import gtk
-import timerapplet.utils as utils
-
-from timerapplet.utils import (serialize_bool,
- deserialize_bool,
- seconds_to_hms,
- hms_to_seconds)
-from timerapplet.defs import VERSION
-
-class PersistentStore(gtk.ListStore):
- def __init__(self, load_func, save_func, *args):
- gtk.ListStore.__init__(self, *args)
- load_func(self)
-
- self.connect('row-deleted', lambda model, row_path: save_func(self))
- self.connect('row-changed', lambda model, row_path, row_iter: save_func(self))
-
-class PresetsStore(gobject.GObject):
- (_NAME_COL,
- _HOURS_COL,
- _MINUTES_COL,
- _SECONDS_COL,
- _COM_COL,
- _NEXT_COL,
- _AUTO_START_COL) = xrange(7)
-
- def __init__(self, filename):
- object.__init__(self)
- self._model = PersistentStore(lambda model: PresetsStore._load_presets(model, filename),
- lambda model: PresetsStore._save_presets(model, filename),
- gobject.TYPE_STRING,
- gobject.TYPE_INT,
- gobject.TYPE_INT,
- gobject.TYPE_INT,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN,
- )
-
- def get_model(self):
- """Return GtkTreeModel.
-
- Should not rely on it being any particular subtype of GtkTreeModel.
-
- """
- return self._model
-
- def get_preset(self, row_iter):
- return self._model.get(row_iter,
- PresetsStore._NAME_COL,
- PresetsStore._HOURS_COL,
- PresetsStore._MINUTES_COL,
- PresetsStore._SECONDS_COL,
- PresetsStore._COM_COL,
- PresetsStore._NEXT_COL,
- PresetsStore._AUTO_START_COL,
- )
-
- def add_preset(self, name, hours, minutes, seconds, command, next_timer,
- auto_start):
- self._model.append((name, hours, minutes, seconds, command, next_timer,
- auto_start))
-
- def modify_preset(self, row_iter, name, hours, minutes, seconds, command,
- next_timer, auto_start):
- self._model.set(row_iter,
- PresetsStore._NAME_COL, name,
- PresetsStore._HOURS_COL, hours,
- PresetsStore._MINUTES_COL, minutes,
- PresetsStore._SECONDS_COL, seconds,
- PresetsStore._COM_COL, command,
- PresetsStore._NEXT_COL, next_timer,
- PresetsStore._AUTO_START_COL, auto_start
- )
-
- def remove_preset(self, row_iter):
- self._model.remove(row_iter)
-
- def preset_name_exists_case_insensitive(self, preset_name):
- preset_name = preset_name.lower()
- for preset in self._model:
- if preset_name == preset[PresetsStore._NAME_COL].lower():
- return True
- return False
-
- def _load_presets(model, file_path):
- try:
- tree = et.parse(file_path)
- except:
- return
-
- root = tree.getroot()
-
- for node in root:
- name = node.get('name')
- (hours, minutes, seconds) = seconds_to_hms(int(node.get('duration')))
- command = node.get('command')
- next_timer = node.get('next_timer')
- auto_start = node.get('auto_start')
- model.append((name, hours, minutes, seconds, command, next_timer,
- deserialize_bool(auto_start)))
- _load_presets = staticmethod(_load_presets)
-
- def _save_presets(model, file_path):
- root = et.Element('timerapplet')
- root.set('version', VERSION)
-
- def add_xml_node(model, path, row_iter):
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- model.get(row_iter,
- PresetsStore._NAME_COL,
- PresetsStore._HOURS_COL,
- PresetsStore._MINUTES_COL,
- PresetsStore._SECONDS_COL,
- PresetsStore._COM_COL,
- PresetsStore._NEXT_COL,
- PresetsStore._AUTO_START_COL
- )
- node = et.SubElement(root, 'preset')
- node.set('name', name)
- node.set('duration', str(hms_to_seconds(hours, minutes, seconds)))
- node.set('command', command or '')
- node.set('next_timer', next_timer or '')
- node.set('auto_start', serialize_bool(auto_start))
-
- model.foreach(add_xml_node)
- tree = et.ElementTree(root)
-
- file_dir = path.dirname(file_path)
- if not path.exists(file_dir):
- print 'Creating config directory: %s' % file_dir
- os.makedirs(file_dir, 0744)
- tree.write(file_path)
- _save_presets = staticmethod(_save_presets)
-
diff --git a/timer-applet/src/timerapplet/core/Timer.py b/timer-applet/src/timerapplet/core/Timer.py
deleted file mode 100644
index d2f8c695..00000000
--- a/timer-applet/src/timerapplet/core/Timer.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import datetime
-import time
-import gobject
-
-class Timer(gobject.GObject):
- (STATE_IDLE, STATE_RUNNING, STATE_PAUSED, STATE_FINISHED) = xrange(4)
-
- __gsignals__ = {'time-changed':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
- 'state-changed':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())}
-
- def __init__(self):
- gobject.GObject.__init__(self)
- self._state = Timer.STATE_IDLE
- self._duration_seconds = 0
- self._remaining_seconds = 0
- self._end_time = 0
- self._name = ''
- self._command = ''
- self._next_timer = ''
- self._auto_start = False
-
- def set_duration(self, seconds):
- """Set the duration of the timer in seconds."""
- assert self._state == Timer.STATE_IDLE
- self._duration_seconds = seconds
-
- def get_duration(self):
- """Return the duration of the timer in seconds."""
- return self._duration_seconds
-
- def set_name(self, name):
- """Set the name of the timer."""
- assert self._state == Timer.STATE_IDLE
- self._name = name
-
- def get_name(self):
- """Return the name of the timer."""
- return self._name
-
- def set_command(self, command):
- """Set the command to run of the timer."""
- assert self._state == Timer.STATE_IDLE
- self._command = command
-
- def get_command(self):
- """Return the name of the command of the timer."""
- return self._command
-
- def set_next_timer(self, timer):
- """Set the next timeer of the timer."""
- assert self._state == Timer.STATE_IDLE
- self._next_timer = timer
-
- def get_next_timer(self):
- """Get the next timer of the timer."""
- return self._next_timer
-
- def set_auto_start(self, auto_start):
- """Set the auto-start value of the timer."""
- assert self._state == Timer.STATE_IDLE
- self._auto_start = auto_start
-
- def get_auto_start(self):
- """Get the auto-start value."""
- return self._auto_start
-
- def start(self):
- """Start or resume the timer.
-
- This method should only be called when the timer is IDLE or PAUSED.
-
- """
- assert self._state == Timer.STATE_IDLE or self._state == Timer.STATE_PAUSED
- self._timer_transition_to_state(Timer.STATE_RUNNING)
-
- def stop(self):
- """Pause the timer.
-
- This method should only be called when the timer is RUNNING.
-
- """
- assert self._state == Timer.STATE_RUNNING
- self._timer_transition_to_state(Timer.STATE_PAUSED)
-
- def reset(self):
- """Reset the timer.
-
- This method should only be called when the timer is not IDLE.
-
- """
- assert self._state != Timer.STATE_IDLE
- self._timer_transition_to_state(Timer.STATE_IDLE)
-
- def get_state(self):
- """Return the current state."""
- return self._state
-
- def get_remaining_time(self):
- """Return the remaining time in seconds."""
- return min(self._duration_seconds, max(0, self._remaining_seconds))
-
- def get_end_time(self):
- """Return a datetime object representing the end time.
-
- This method should only be called when the timer is RUNNING or FINISHED.
-
- """
- assert self._state == Timer.STATE_RUNNING or self._state == Timer.STATE_FINISHED
- return datetime.datetime.fromtimestamp(self._end_time)
-
- def _timer_set_state(self, state):
- self._state = state
- self.emit('state-changed')
-
- def _timer_transition_to_state(self, dest_state):
- cur_time = int(time.time())
-
- if dest_state == Timer.STATE_IDLE:
- self._end_time = 0
- self._set_remaining_time(self._duration_seconds)
- elif dest_state == Timer.STATE_RUNNING:
- assert self._duration_seconds >= 0
-
- if self._state == Timer.STATE_IDLE:
- self._end_time = cur_time + self._duration_seconds
- self._set_remaining_time(self._duration_seconds)
- elif self._state == Timer.STATE_PAUSED:
- self._end_time = cur_time + self._remaining_seconds
-
- gobject.timeout_add(500, self._on_timeout)
- elif dest_state == Timer.STATE_PAUSED:
- self._set_remaining_time(self._end_time - cur_time)
- self._end_time = 0
- elif dest_state == Timer.STATE_FINISHED:
- pass
- else:
- assert False
-
- self._timer_set_state(dest_state)
-
- def _on_timeout(self):
- if self._state != Timer.STATE_RUNNING:
- return False # remove timeout source
-
- new_remaining = self._end_time - int(time.time())
- if self._remaining_seconds != new_remaining:
- self._set_remaining_time(new_remaining)
-
- if self._remaining_seconds < 0:
- self._timer_transition_to_state(Timer.STATE_FINISHED)
- return False # remove timeout source
- return True # keep timeout source
-
- def _set_remaining_time(self, new_remaining):
- self._remaining_seconds = new_remaining
- self.emit('time-changed')
diff --git a/timer-applet/src/timerapplet/core/__init__.py b/timer-applet/src/timerapplet/core/__init__.py
deleted file mode 100644
index 257837d5..00000000
--- a/timer-applet/src/timerapplet/core/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from Timer import Timer
-from PresetsStore import PresetsStore
-from AppletMateConfWrapper import AppletMateConfWrapper
diff --git a/timer-applet/src/timerapplet/defs.py.in b/timer-applet/src/timerapplet/defs.py.in
deleted file mode 100644
index 55087654..00000000
--- a/timer-applet/src/timerapplet/defs.py.in
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGE = '@PACKAGE@'
-VERSION = '@VERSION@'
-GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@'
-LOCALE_DIR = '@LOCALEDIR@'
-RESOURCES_DIR = '@RESOURCESDIR@'
-IMAGES_DIR = '@IMAGESDIR@'
-
diff --git a/timer-applet/src/timerapplet/logger.py b/timer-applet/src/timerapplet/logger.py
deleted file mode 100644
index 489ee9c4..00000000
--- a/timer-applet/src/timerapplet/logger.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import logging
-
-logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(levelname)-8s %(message)s',
- datefmt='%a, %d %b %Y %H:%M:%S',
- filename='/tmp/myapp.log',
- filemode='w')
diff --git a/timer-applet/src/timerapplet/ui/AddEditPresetDialog.py b/timer-applet/src/timerapplet/ui/AddEditPresetDialog.py
deleted file mode 100644
index ce9d0aee..00000000
--- a/timer-applet/src/timerapplet/ui/AddEditPresetDialog.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gtk
-import gtk.glade as glade
-from DurationChooser import DurationChooser
-
-class AddEditPresetDialog(object):
- def __init__(self, glade_file_name, title, name_validator_func,
- name='', hours=0, minutes=0, seconds=0, command='',
- next_timer='', auto_start=False):
- self._valid_name_func = name_validator_func
-
- glade_widgets = glade.XML(glade_file_name, 'add_edit_preset_dialog')
- self._dialog = glade_widgets.get_widget('add_edit_preset_dialog')
- self._ok_button = glade_widgets.get_widget('ok_button')
- self._cancel_button = glade_widgets.get_widget('cancel_button')
- self._name_entry = glade_widgets.get_widget('name_entry')
- duration_chooser_container = glade_widgets.get_widget('duration_chooser_container')
- self._duration_chooser = DurationChooser(gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL))
- self._command_entry = glade_widgets.get_widget('command_entry')
- self._next_timer_entry = glade_widgets.get_widget('next_timer_entry')
- self._auto_start_check = glade_widgets.get_widget('auto_start_check')
-
- duration_chooser_container.pack_start(self._duration_chooser)
-
- self._dialog.set_title(title)
- self._dialog.set_default_response(gtk.RESPONSE_OK)
- self._name_entry.set_text(name)
- self._command_entry.set_text(command)
- self._duration_chooser.set_duration(hours, minutes, seconds)
- self._next_timer_entry.set_text(next_timer)
- self._auto_start_check.set_active(auto_start)
-
- self._name_entry.connect('changed', lambda entry: self._check_for_valid_save_preset_input())
- self._duration_chooser.connect('duration-changed',
- lambda chooser: self._check_for_valid_save_preset_input())
- self._duration_chooser.show()
-
- def _non_zero_duration(self):
- (hours, minutes, seconds) = self._duration_chooser.get_duration()
- return (hours > 0 or minutes > 0 or seconds > 0)
-
- def _check_for_valid_save_preset_input(self):
- self._ok_button.props.sensitive = (self._non_zero_duration() and
- self._valid_name_func(self._name_entry.get_text()))
-
- ## Callback for saving ##
-
- def get_preset(self):
- self._check_for_valid_save_preset_input()
- result = self._dialog.run()
- self._dialog.hide()
- if result == gtk.RESPONSE_OK:
- (hours, minutes, seconds) = self._duration_chooser.get_duration()
- cmd = self._command_entry.get_text()
- next_timer = self._next_timer_entry.get_text()
- auto_start = self._auto_start_check.get_active()
- return (self._name_entry.get_text(), hours, minutes, seconds, cmd,
- next_timer, auto_start)
- else:
- return None
diff --git a/timer-applet/src/timerapplet/ui/ContinueTimerDialog.py b/timer-applet/src/timerapplet/ui/ContinueTimerDialog.py
deleted file mode 100644
index 5353139f..00000000
--- a/timer-applet/src/timerapplet/ui/ContinueTimerDialog.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from gettext import gettext as _
-import gtk
-
-class ContinueTimerDialog(object):
- (STOP_TIMER, KEEP_PAUSED, CONTINUE_TIMER) = xrange(3)
-
- def __init__(self, glade_file_name, header_text, body_text):
- self._dialog = gtk.Dialog(_('Continue Timer'),
- None,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- (_('_Stop Timer'), gtk.RESPONSE_NO,
- _('_Keep Paused'), gtk.RESPONSE_CLOSE,
- _('_Continue Timer'), gtk.RESPONSE_YES))
- self._dialog.props.border_width = 6
- self._dialog.props.has_separator = False
- self._dialog.props.resizable = False
- self._dialog.vbox.props.spacing = 12
- self._dialog.set_default_response(gtk.RESPONSE_YES)
-
- hbox = gtk.HBox(False, 0)
- hbox.props.spacing = 12
- hbox.props.border_width = 6
-
- image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG)
- image.props.yalign = 0.0
-
- label = gtk.Label('<span weight="bold" size="larger">%s</span>\n\n%s' % (header_text, body_text))
- label.props.use_markup = True
- label.props.wrap = True
- label.props.yalign = 0.0
-
- hbox.pack_start(image, False, False, 0)
- hbox.pack_start(label, False, False, 0)
- self._dialog.vbox.pack_start(hbox, False, False, 0)
-
- hbox.show_all()
-
- def get_response(self):
- dialog_result = self._dialog.run()
- self._dialog.hide()
- if dialog_result == gtk.RESPONSE_YES:
- return ContinueTimerDialog.CONTINUE_TIMER
- elif dialog_result == gtk.RESPONSE_NO:
- return ContinueTimerDialog.STOP_TIMER
- else:
- return ContinueTimerDialog.KEEP_PAUSED
-
diff --git a/timer-applet/src/timerapplet/ui/DurationChooser.py b/timer-applet/src/timerapplet/ui/DurationChooser.py
deleted file mode 100644
index bd8d35ae..00000000
--- a/timer-applet/src/timerapplet/ui/DurationChooser.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from gettext import gettext as _
-import math
-import gobject
-import gtk
-
-class DurationChooser(gtk.VBox):
- __gsignals__ = {'duration-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())}
- MAX_HOURS = 48
- MAX_MINUTES = 999
- MAX_SECONDS = 999
-
- def __init__(self, size_group):
- gtk.VBox.__init__(self, False, 6)
-
- self._hours_spin = self._add_row(_('_Hours:'),
- size_group,
- DurationChooser.MAX_HOURS)
- self._minutes_spin = self._add_row(_('_Minutes:'),
- size_group,
- DurationChooser.MAX_MINUTES)
- self._seconds_spin = self._add_row(_('_Seconds:'),
- size_group,
- DurationChooser.MAX_SECONDS)
-
- def get_duration(self):
- """Return numerical representations of the values in the spinbuttons.
-
- This method does not just call get_value_as_int() on each spinbutton because
- get_value_as_int() does not return the most up-to-date value if the user is
- in the middle of editing the value in a spinbutton. Instead, it actually
- returns the value previously "confirmed" for the spinbutton (for example,
- by moving focus to another widget).
-
- Example: User starts with all spinboxes set to 0. He types 5 in 'Minutes' and
- immediately uses the keyboard to activate the 'Save as Preset' button. Because
- the user never moved focus out of the spinbutton, get_value_as_int() will report
- the previous value of 0, and the saved preset will not have the expected duration
- of 5 minutes.
-
- If a particular spinbutton is empty or contains a non-float value, then this method
- will report its value as zero.
-
- Returns a tuple in this format: (hours, minutes, seconds)
-
- """
- hours_str = self._hours_spin.props.text
- minutes_str = self._minutes_spin.props.text
- seconds_str = self._seconds_spin.props.text
- hours = 0
- minutes = 0
- seconds = 0
-
- try:
- hours = float(hours_str)
- except TypeError:
- pass
- except ValueError:
- pass
-
- try:
- minutes = float(minutes_str)
- except TypeError:
- pass
- except ValueError:
- pass
-
- try:
- seconds = float(seconds_str)
- except TypeError:
- pass
- except ValueError:
- pass
-
- minutes_fraction = minutes - int(minutes)
- hours_fraction = hours - int(hours)
-
- # Distribute overflow from seconds to minutes to hours.
- if seconds > 59:
- minutes = math.floor(seconds / 60)
- seconds = seconds % 60
- if minutes > 59:
- hours = math.floor(minutes / 60)
- minutes = minutes % 60
- if hours > DurationChooser.MAX_HOURS:
- hours = DurationChooser.MAX_HOURS
-
- # Distribute fractions.
- if hours_fraction > 0:
- minutes = int(hours_fraction * 60)
- if minutes_fraction > 0:
- seconds = int(minutes_fraction * 60)
-
- return (int(hours), int(minutes), int(seconds))
-
- def set_duration(self, hours, minutes, seconds):
- self._hours_spin.set_value(hours)
- self._minutes_spin.set_value(minutes)
- self._seconds_spin.set_value(seconds)
-
- def normalize_fields(self):
- (hours, minutes, seconds) = self.get_duration()
- self._hours_spin.set_value(hours)
- self._minutes_spin.set_value(minutes)
- self._seconds_spin.set_value(seconds)
-
- def clear(self):
- self._hours_spin.set_value(0)
- self._minutes_spin.set_value(0)
- self._seconds_spin.set_value(0)
-
- def focus_hours(self):
- self._hours_spin.grab_focus()
-
- def _add_row(self, row_label_str, size_group, max_spin_val):
- row_hbox = gtk.HBox(False, 6)
-
- label = gtk.Label(row_label_str)
- label.set_property('xalign', 0.0)
- label.set_property('use-underline', True)
- size_group.add_widget(label)
-
- spin_adj = gtk.Adjustment(0, 0, max_spin_val, 1, 1, 0)
- spin_button = gtk.SpinButton(spin_adj, 1.0, 0)
- spin_button.props.activates_default = True
- spin_button.props.numeric = False
- spin_button.props.update_policy = gtk.UPDATE_IF_VALID
-
- label.set_mnemonic_widget(spin_button)
-
- row_hbox.pack_start(label, False, False, 0)
- row_hbox.pack_start(spin_button, True, True, 0)
- self.pack_start(row_hbox, False, False, 0)
-
- spin_button.connect('changed', self._on_spin_button_val_changed)
- spin_button.connect('focus-out-event', self._on_spin_button_focus_out)
- spin_button.connect('activate', self._on_spin_button_activate)
-
- label.show()
- spin_button.show()
- row_hbox.show()
- return spin_button
-
- def _on_spin_button_val_changed(self, spin_button):
- self.emit('duration-changed')
-
- def _on_spin_button_focus_out(self, spin_button, event):
- self.normalize_fields()
-
- def _on_spin_button_activate(self, entry):
- self.normalize_fields()
diff --git a/timer-applet/src/timerapplet/ui/Makefile.am b/timer-applet/src/timerapplet/ui/Makefile.am
deleted file mode 100644
index 0021823e..00000000
--- a/timer-applet/src/timerapplet/ui/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-moduledir = $(pythondir)/timerapplet/ui
-module_PYTHON = \
- __init__.py \
- AddEditPresetDialog.py \
- ContinueTimerDialog.py \
- DurationChooser.py \
- ManagePresetsDialog.py \
- Notifier.py \
- PieMeter.py \
- PreferencesDialog.py \
- PulseButton.py \
- ScrollableButtonList.py \
- StartTimerDialog.py \
- StartNextTimerDialog.py \
- StatusButton.py
diff --git a/timer-applet/src/timerapplet/ui/ManagePresetsDialog.py b/timer-applet/src/timerapplet/ui/ManagePresetsDialog.py
deleted file mode 100644
index 80f97bdb..00000000
--- a/timer-applet/src/timerapplet/ui/ManagePresetsDialog.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gobject
-import gtk
-import gtk.glade as glade
-
-class ManagePresetsDialog(gobject.GObject):
- __gsignals__ = {'clicked-add':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
- 'clicked-edit':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
- 'clicked-remove':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,))}
-
- def __init__(self, glade_file_name, presets_store, preset_display_func):
- gobject.GObject.__init__(self)
-
- glade_widgets = glade.XML(glade_file_name, 'manage_presets_dialog')
- self._dialog = glade_widgets.get_widget('manage_presets_dialog')
- self._presets_view = glade_widgets.get_widget('presets_view')
- self._delete_button = glade_widgets.get_widget('delete_button')
- self._edit_button = glade_widgets.get_widget('edit_button')
- self._add_button = glade_widgets.get_widget('add_button')
-
- self._presets_view.set_model(presets_store)
- renderer = gtk.CellRendererText()
- col = gtk.TreeViewColumn('Preset', renderer)
-
- def preset_cell_data_func(col, cell, model, row_iter, user_data=None):
- cell.props.text = preset_display_func(row_iter)
-
- col.set_cell_data_func(renderer, preset_cell_data_func)
- self._presets_view.append_column(col)
-
- self._dialog.connect('response', self._on_dialog_response)
- self._dialog.connect('delete-event', self._dialog.hide_on_delete)
- self._presets_view.get_selection().connect('changed', lambda selection: self._update_button_states())
- self._delete_button.connect('clicked', self._on_delete_button_clicked)
- self._edit_button.connect('clicked', self._on_edit_button_clicked)
- self._add_button.connect('clicked', self._on_add_button_clicked)
-
- self._update_button_states()
- self._dialog.set_default_size(300, 220)
-
- def show(self):
- self._dialog.present()
-
- def _get_selected_path(self):
- selection = self._presets_view.get_selection()
- (model, selection_iter) = selection.get_selected()
- return model.get_path(selection_iter)
-
- def _update_button_states(self):
- selection = self._presets_view.get_selection()
- num_selected = selection.count_selected_rows()
- self._delete_button.props.sensitive = num_selected >= 1
- self._edit_button.props.sensitive = num_selected == 1
-
- def _on_delete_button_clicked(self, button):
- row_path = self._get_selected_path()
- self.emit('clicked-remove', row_path)
-
- def _on_edit_button_clicked(self, button):
- row_path = self._get_selected_path()
- self.emit('clicked-edit', row_path)
-
- def _on_add_button_clicked(self, button):
- self.emit('clicked-add')
-
- def _on_dialog_response(self, dialog, response_id):
- dialog.hide()
-
diff --git a/timer-applet/src/timerapplet/ui/Notifier.py b/timer-applet/src/timerapplet/ui/Notifier.py
deleted file mode 100644
index 91db1517..00000000
--- a/timer-applet/src/timerapplet/ui/Notifier.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gobject
-import pynotify
-
-class Notifier(object):
- _NOTIFICATION_REDISPLAY_INTERVAL_SECONDS = 60
-
- def __init__(self, app_name, icon, attach):
- self._icon = icon
- self._attach = attach
- self._notify = None
- self._handler_id = None
- self._timeout_id = None
-
- if not pynotify.is_initted():
- pynotify.init(app_name)
-
- def begin(self, summary, body, get_reminder_message_func):
- # NOTE: This callback wrapper is to workaround an API-breaking change present in
- # the version of libmatenotify used by Fedora 10. The API break adds an additional
- # 'reason' parameter to the callback signature. This was fixed before
- # the latest official release of libmatenotify, but it looks like Fedora 10
- # is using an unofficial libmatenotify build that still contains the API-breaking change.
- def closed_callback_wrapper(notification, reason_UNUSED=None):
- self._on_notification_closed(notification, get_reminder_message_func)
-
- self.end()
- self._notify = pynotify.Notification(summary, body, self._icon)
- self._handler_id = self._notify.connect('closed', closed_callback_wrapper)
- self._notify.show()
-
- def end(self):
- if self._notify is not None:
- if self._timeout_id is not None:
- gobject.source_remove(self._timeout_id)
- self._timeout_id = None
- self._notify.disconnect(self._handler_id)
- self._handler_id = None
- try:
- self._notify.close()
- except gobject.GError:
- # Throws a GError exception if the notification bubble has already been closed.
- # Ignore the exception.
- pass
- self._notify = None
-
- def _on_notification_closed(self, notification, get_reminder_message_func):
- self._timeout_id = gobject.timeout_add(Notifier._NOTIFICATION_REDISPLAY_INTERVAL_SECONDS * 1000,
- self._on_notification_redisplay_timeout,
- get_reminder_message_func)
-
- def _on_notification_redisplay_timeout(self, get_reminder_message_func):
- message = get_reminder_message_func()
- self._notify.props.body = message
- self._notify.show()
-
- self._timeout_id = None
- return False
diff --git a/timer-applet/src/timerapplet/ui/PieMeter.py b/timer-applet/src/timerapplet/ui/PieMeter.py
deleted file mode 100644
index 9bec5e5c..00000000
--- a/timer-applet/src/timerapplet/ui/PieMeter.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import math
-import gobject
-import gtk
-
-class PieMeter(gtk.Image):
- _DEFAULT_SIZE = 24
-
- def __init__(self):
- gtk.Image.__init__(self)
- self._progress = 0.0
- self._fill_color = (0.0, 1.0, 0.0)
-
- def set_progress(self, progress):
- assert progress >= 0.0
- assert progress <= 1.0
- self._progress = progress
- if self.window is not None:
- self.window.invalidate_rect(self.allocation, True)
-
- def set_fill_color(self, red, green, blue):
- assert 0.0 <= red <= 1.0
- assert 0.0 <= green <= 1.0
- assert 0.0 <= blue <= 1.0
- self._fill_color = (red, green, blue)
-
- if self.window is not None:
- self.window.invalidate_rect(self.allocation, True)
-
- def do_size_request(self, requisition):
- requisition.width = PieMeter._DEFAULT_SIZE
- requisition.height = PieMeter._DEFAULT_SIZE
-
- def do_expose_event(self, event):
- context = event.window.cairo_create()
-
- rect = self.allocation
- x = rect.x + (rect.width / 2)
- y = rect.y + (rect.height / 2)
- radius = (min(rect.width, rect.height) / 2)
-
- # Draw background circle
- context.arc(x, y, radius, 0, 2 * math.pi)
- context.set_source_rgba(0.8, 0.8, 0.8)
- context.fill()
-
- # Draw pie
- context.arc(x, y, radius, (-0.5 * math.pi) + self._progress * 2 * math.pi, 1.5 * math.pi)
- context.line_to(x, y)
- context.close_path()
- (red, green, blue) = self._fill_color
- context.set_source_rgb(red, green, blue)
- context.fill()
-
- # Draw circle outline
- context.arc(x, y, radius, 0, 2 * math.pi)
- context.set_source_rgba(1, 1, 1)
- context.set_line_width(1.0)
- context.stroke()
-
-gobject.type_register(PieMeter)
-
diff --git a/timer-applet/src/timerapplet/ui/PreferencesDialog.py b/timer-applet/src/timerapplet/ui/PreferencesDialog.py
deleted file mode 100644
index d42ae911..00000000
--- a/timer-applet/src/timerapplet/ui/PreferencesDialog.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gobject
-import gtk
-import gtk.glade as glade
-
-class PreferencesDialog(gobject.GObject):
- __gsignals__ = \
- {
- 'show-remaining-time-changed':
- (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN,)
- ),
- 'play-sound-changed':
- (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN,)
- ),
- 'use-custom-sound-changed':
- (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN,)
- ),
- 'show-popup-notification-changed':
- (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN,)
- ),
- 'show-pulsing-icon-changed':
- (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN,)
- ),
- 'custom-sound-path-changed':
- (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING,)
- )
- }
-
- __gproperties__ = \
- {
- 'show-remaining-time':
- (bool,
- 'Show remaining time',
- 'Whether to show remaining time when the timer is running',
- False,
- gobject.PARAM_WRITABLE
- ),
- 'play-sound':
- (bool,
- 'Play notification sound',
- 'Whether to play notification sound when the timer is finished',
- False,
- gobject.PARAM_WRITABLE
- ),
- 'use-custom-sound':
- (bool,
- 'Use custom sound',
- 'Whether to use a custom notification sound',
- False,
- gobject.PARAM_WRITABLE
- ),
- 'show-popup-notification':
- (bool,
- 'Show Popup notification',
- 'Whether to show a popup notifcation when timer finished',
- False,
- gobject.PARAM_WRITABLE
- ),
- 'show-pulsing-icon':
- (bool,
- 'Show pulsing icon',
- 'Whether to show pulsing icon when timer finished',
- False,
- gobject.PARAM_WRITABLE
- ),
- 'custom-sound-path':
- (str,
- 'Custom sound path',
- 'Path to a custom notification sound',
- '',
- gobject.PARAM_WRITABLE
- )
- }
-
- def __init__(self, glade_file_name):
- gobject.GObject.__init__(self)
- glade_widgets = glade.XML(glade_file_name, 'preferences_dialog')
- self._preferences_dialog = glade_widgets.get_widget('preferences_dialog')
- self._show_time_check = glade_widgets.get_widget('show_time_check')
- self._play_sound_check = glade_widgets.get_widget('play_sound_check')
- self._use_default_sound_radio = glade_widgets.get_widget('use_default_sound_radio')
- self._use_custom_sound_radio = glade_widgets.get_widget('use_custom_sound_radio')
- self._sound_chooser_button = glade_widgets.get_widget('sound_chooser_button')
- self._play_sound_box = glade_widgets.get_widget('play_sound_box')
- #: Popup notification checkbutton
- self._popup_notification_check = glade_widgets.get_widget('popup_notification_check')
- #: Pulsing icon checkbutton
- self._pulsing_icon_check = glade_widgets.get_widget('pulsing_trayicon_check')
-
- #######################################################################
- # Signals
- #######################################################################
- self._show_time_check.connect('toggled', self._on_show_time_check_toggled)
- self._play_sound_check.connect('toggled', self._on_play_sound_check_toggled)
- self._use_custom_sound_radio.connect('toggled', self._on_use_custom_sound_radio_toggled)
- #: Popup notification checkbutton 'toggled' signal
- self._popup_notification_check.connect('toggled', self._on_popup_notification_toggled)
- #: Pulsing icon checkbutton 'toggled' signal
- self._pulsing_icon_check.connect('toggled', self._on_pulsing_icon_toggled)
-
- self._sound_chooser_button.connect('selection-changed', self._on_sound_chooser_button_selection_changed)
- self._preferences_dialog.connect('delete-event', gtk.Widget.hide_on_delete)
- self._preferences_dialog.connect('response', lambda dialog, response_id: self._preferences_dialog.hide())
-
- def show(self):
- self._preferences_dialog.present()
-
- def _on_show_time_check_toggled(self, widget):
- self.emit('show-remaining-time-changed', widget.props.active)
-
- def _on_play_sound_check_toggled(self, widget):
- self.emit('play-sound-changed', widget.props.active)
-
- def _on_use_custom_sound_radio_toggled(self, widget):
- self.emit('use-custom-sound-changed', widget.props.active)
-
- def _on_popup_notification_toggled(self, widget):
- """Emit a signal when `self._popup_notification_check` gets toggled in
- the Preferences dialog window."""
- self.emit('show-popup-notification-changed', widget.props.active)
-
- def _on_pulsing_icon_toggled(self, widget):
- """Emit a signal when `self._popup_notification_check` gets toggled in
- the Preferences dialog window."""
- self.emit('show-pulsing-icon-changed', widget.props.active)
-
- def _on_sound_chooser_button_selection_changed(self, chooser_button):
- filename = chooser_button.get_filename()
-
- # Work around an issue where calling set_filename() will cause
- # 3 selection-changed signals to be emitted: first two will have a None filename
- # and the third will finally have the desired filename.
- if filename is not None:
- print 'Custom sound changed to path: %s' % filename
- self.emit('custom-sound-path-changed', filename)
-
- def do_set_property(self, pspec, value):
- if pspec.name == 'show-remaining-time':
- self._show_time_check.props.active = value
- elif pspec.name == 'play-sound':
- self._play_sound_check.props.active = value
- self._play_sound_box.props.sensitive = value
- elif pspec.name == 'use-custom-sound':
- if value == True:
- self._use_custom_sound_radio.props.active = True
- self._sound_chooser_button.props.sensitive = True
- else:
- # Note: Setting _use_custom_sound_radio.props.active to False
- # does not automatically set _use_default_sound_radio.props.active to True
- self._use_default_sound_radio.props.active = True
- self._sound_chooser_button.props.sensitive = False
- elif pspec.name == 'show-popup-notification':
- self._popup_notification_check.props.active = value
- elif pspec.name == 'show-pulsing-icon':
- self._pulsing_icon_check.props.active = value
- elif pspec.name == 'custom-sound-path':
- # Prevent infinite loop of events.
- if self._sound_chooser_button.get_filename() != value:
- self._sound_chooser_button.set_filename(value)
diff --git a/timer-applet/src/timerapplet/ui/PulseButton.py b/timer-applet/src/timerapplet/ui/PulseButton.py
deleted file mode 100644
index 9694ea48..00000000
--- a/timer-applet/src/timerapplet/ui/PulseButton.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import math
-import time
-import gobject
-import gtk
-
-class PulseButton(gtk.Button):
- def __init__(self):
- super(PulseButton, self).__init__()
-
- self._anim_period_seconds = 0.7
- self._start_time = 0.0
- self._factor = 0.0
-
- def start_pulsing(self):
- self._start_time = time.time()
- gobject.timeout_add(10, self._on_timeout)
-
- def stop_pulsing(self):
- self._start_time = 0
-
- def _on_timeout(self, data=None):
- if self._start_time <= 0.0:
- return False
- if self.window != None:
- delta = time.time() - self._start_time
-
- if delta > self._anim_period_seconds:
- delta = self._anim_period_seconds
- self._start_time = time.time()
- fraction = delta/self._anim_period_seconds
- self._factor = math.sin(fraction * math.pi)
-
- self.window.invalidate_rect(self.allocation, True)
- return True
-
- def do_expose_event(self, event):
- gtk.Button.do_expose_event(self, event)
- if self._start_time > 0:
- context = event.window.cairo_create()
- context.rectangle(0, 0, self.allocation.width, self.allocation.height)
-
- #color = self.style.bg[gtk.STATE_SELECTED]
- #color = gtk.gdk.Color(65535, 65535, 65535)
- color = gtk.gdk.Color(0, 0, 0)
- red = color.red / 65535.0
- green = color.green / 65535.0
- blue = color.blue / 65535.0
- context.set_source_rgba(red, green, blue, self._factor * 0.8)
- context.fill()
-
- return False
-
-gobject.type_register(PulseButton)
diff --git a/timer-applet/src/timerapplet/ui/ScrollableButtonList.py b/timer-applet/src/timerapplet/ui/ScrollableButtonList.py
deleted file mode 100644
index 0af6e51d..00000000
--- a/timer-applet/src/timerapplet/ui/ScrollableButtonList.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gtk
-
-def get_scroll_value_to_reveal_widget(widget_rect, viewport_rect, scroll_val):
- if widget_rect.y < scroll_val:
- scroll_val = widget_rect.y
- elif widget_rect.y + widget_rect.height + 1 > scroll_val + viewport_rect.height:
- scroll_val = widget_rect.y + widget_rect.height + 1 - viewport_rect.height
- return scroll_val
-
-class ScrollableButtonList(gtk.ScrolledWindow):
- def __init__(self):
- gtk.ScrolledWindow.__init__(self)
-
- self._vadjust = gtk.Adjustment()
- self._vbox = gtk.VBox()
- self._viewport = gtk.Viewport()
-
- self.set_vadjustment(self._vadjust)
- self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self._viewport.modify_bg(gtk.STATE_NORMAL, self.style.base[gtk.STATE_NORMAL])
-
- self._viewport.add(self._vbox)
- self.add(self._viewport)
-
- self._vbox.show()
- self._viewport.show()
-
- def add_button(self, button):
- button.connect('focus-in-event', self._on_focus)
- button.connect('clicked', self._on_clicked)
- self._vbox.pack_start(button, False, False)
-
- def get_buttons(self):
- return self._vbox.get_children()
-
- def _on_focus(self, widget, event):
- self._scroll_to_widget(widget)
-
- def _on_clicked(self, widget):
- self._scroll_to_widget(widget)
-
- def _scroll_to_widget(self, widget):
- cur_val = self._vadjust.get_value()
- new_val = get_scroll_value_to_reveal_widget(widget.allocation, self._viewport.allocation, cur_val)
-
- if new_val != cur_val:
- self._vadjust.set_value(new_val)
- self._vadjust.value_changed()
-
diff --git a/timer-applet/src/timerapplet/ui/StartNextTimerDialog.py b/timer-applet/src/timerapplet/ui/StartNextTimerDialog.py
deleted file mode 100644
index 11886c87..00000000
--- a/timer-applet/src/timerapplet/ui/StartNextTimerDialog.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- mode: python; coding: utf-8; -*-
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-"""
-The Start Next Timer dialog
-
-When a timer ended and the auto_start option was disabled this dialog shows up.
-"""
-
-from gettext import gettext as _
-import gtk
-
-class StartNextTimerDialog(object):
- def __init__(self, glade_file_name, header_text, body_text):
- # TODO: Include next_timer in body_text
- self._dialog = gtk.Dialog(
- _("Start Next Timer"),
- None,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- (_("_Don't start next timer"), gtk.RESPONSE_CLOSE,
- _("_Start next timer"), gtk.RESPONSE_YES))
- self._dialog.props.border_width = 6
- self._dialog.props.has_separator = False
- self._dialog.props.resizable = False
- self._dialog.vbox.props.spacing = 12
- self._dialog.set_default_response(gtk.RESPONSE_YES)
-
- hbox = gtk.HBox(False, 0)
- hbox.props.spacing = 12
- hbox.props.border_width = 6
-
- image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG)
- image.props.yalign = 0.0
-
- label = gtk.Label('<span weight="bold" size="larger">%s</span>\n\n%s' % (header_text, body_text))
- label.props.use_markup = True
- label.props.wrap = True
- label.props.yalign = 0.0
-
- hbox.pack_start(image, False, False, 0)
- hbox.pack_start(label, False, False, 0)
- self._dialog.vbox.pack_start(hbox, False, False, 0)
-
- hbox.show_all()
-
- def get_response(self):
- dialog_result = self._dialog.run()
- self._dialog.hide()
- if dialog_result == gtk.RESPONSE_YES:
- return True
- else:
- return False
-
diff --git a/timer-applet/src/timerapplet/ui/StartTimerDialog.py b/timer-applet/src/timerapplet/ui/StartTimerDialog.py
deleted file mode 100644
index 3d0b4f49..00000000
--- a/timer-applet/src/timerapplet/ui/StartTimerDialog.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gobject
-import gtk
-import gtk.glade as glade
-import gtk.gdk as gdk
-import pango
-
-from gettext import gettext as _
-from shlex import split as shell_tokenize
-from subprocess import check_call, CalledProcessError
-
-from DurationChooser import DurationChooser
-from ScrollableButtonList import ScrollableButtonList
-
-class StartTimerDialog(gobject.GObject):
- __gsignals__ = {'clicked-start':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
- 'clicked-cancel':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
- 'clicked-manage-presets':
- (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
- 'clicked-save':
- (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING,
- gobject.TYPE_INT,
- gobject.TYPE_INT,
- gobject.TYPE_INT,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN)),
- 'clicked-preset':
- (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT,)),
- 'double-clicked-preset':
- (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT,))}
-
- def __init__(self, glade_file_name, name_validator_func, presets_store, preset_display_func):
- gobject.GObject.__init__(self)
-
- self._valid_name_func = name_validator_func;
- self._presets_store = presets_store
- self._preset_display_func = preset_display_func
-
- self._presets_list = ScrollableButtonList()
- labels_size_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
- self._duration_chooser = DurationChooser(labels_size_group)
-
- glade_widgets = glade.XML(glade_file_name, 'start_timer_dialog')
- self._dialog = glade_widgets.get_widget('start_timer_dialog')
- self._ok_button = glade_widgets.get_widget('ok_button')
- name_label = glade_widgets.get_widget('name_label')
- self._name_entry = glade_widgets.get_widget('name_entry')
- self._save_button = glade_widgets.get_widget('save_button')
- duration_chooser_container = glade_widgets.get_widget('duration_chooser_container')
- presets_chooser_container = glade_widgets.get_widget('presets_chooser_container')
- self._presets_section = glade_widgets.get_widget('presets_section')
- #: The TextEntry control for running a custom command
- self._command_entry = glade_widgets.get_widget('command_entry')
- #: The "Invalid Command" label
- self._invalid_cmd_label = glade_widgets.get_widget('invalid_command_label')
- #: The next timer combo box
- self._next_timer_combo = glade_widgets.get_widget('next_timer_combo_entry')
- self._next_timer_combo.set_model(self._presets_store)
- self._next_timer_combo.set_text_column(0) # The column to be shown
- #: The auto-start check button.
- self._auto_start_check = glade_widgets.get_widget('auto_start_check')
-
- labels_size_group.add_widget(name_label)
- self._dialog.set_default_response(gtk.RESPONSE_OK)
- duration_chooser_container.pack_start(self._duration_chooser)
- presets_chooser_container.pack_start(self._presets_list)
-
- self._dialog.connect('response', self._on_dialog_response)
- self._dialog.connect('delete-event', self._dialog.hide_on_delete)
- self._dialog.add_events(gdk.BUTTON_PRESS_MASK)
- self._duration_chooser.connect('duration-changed', self._on_duration_changed)
- self._name_entry.connect('changed', self._on_name_entry_changed)
- self._save_button.connect('clicked', self._on_save_button_clicked)
- # Check that executable is valid while inserting text
- self._command_entry.connect('changed', self._check_is_valid_command)
- self._next_timer_combo.child.connect("changed",
- self._on_next_timer_combo_entry_child_changed)
- glade_widgets.get_widget('manage_presets_button').connect('clicked',
- self._on_manage_presets_button_clicked)
- self._presets_store.connect('row-deleted',
- lambda model, row_path: self._update_presets_list())
- self._presets_store.connect('row-changed',
- lambda model, row_path, row_iter: self._update_presets_list())
-
- self._update_presets_list()
- self._duration_chooser.show()
- self._presets_list.show()
-
- def show(self):
- if not self._dialog.props.visible:
- self._duration_chooser.clear()
- self._duration_chooser.focus_hours()
- self._name_entry.set_text('')
- self._check_for_valid_start_timer_input()
- self._check_for_valid_save_preset_input()
- self._dialog.present()
-
- def hide(self):
- self._dialog.hide()
-
- def get_control_data(self):
- """Return name and duration in a tuple.
-
- The returned tuple is in this format:
-
- (name, hours, minutes, seconds, next_timer, auto_start)
-
- """
- return (self._name_entry.get_text().strip(),) + \
- self._duration_chooser.get_duration() + \
- (self._command_entry.get_text().strip(),
- self._next_timer_combo.child.get_text().strip(),
- self._auto_start_check.get_active())
-
- def set_name_and_duration(self, name, hours, minutes, seconds, *args):
- self._name_entry.set_text(name)
- self._command_entry.set_text(args[0])
- self._next_timer_combo.child.set_text(args[1])
- self._auto_start_check.set_active(args[2])
- self._duration_chooser.set_duration(hours, minutes, seconds)
-
- def _update_presets_list(self):
- self._check_for_valid_save_preset_input()
-
- if len(self._presets_store) == 0:
- self._presets_section.hide()
-
- # Make window shrink
- self._dialog.resize(1, 1)
- else:
- self._presets_section.show()
-
- for button in self._presets_list.get_buttons():
- button.destroy()
-
- row_iter = self._presets_store.get_iter_first()
- while row_iter is not None:
- name = self._preset_display_func(row_iter)
- label = gtk.Label(name)
- label.set_ellipsize(pango.ELLIPSIZE_END)
- button = gtk.Button()
- button.set_relief(gtk.RELIEF_NONE)
- button.add(label)
- self._presets_list.add_button(button)
-
- button.connect('clicked',
- self._on_preset_button_clicked,
- self._presets_store.get_path(row_iter))
- button.connect('button_press_event',
- self._on_preset_button_double_clicked,
- self._presets_store.get_path(row_iter))
-
- label.show()
- button.show()
-
- row_iter = self._presets_store.iter_next(row_iter)
-
- def _check_is_valid_command(self, widget, data=None):
- """
- Check that input in the command entry TextBox control is a valid
- executable.
- """
- try:
- data = widget.get_text()
- executable = shell_tokenize(data)[0]
- # Check if command in path, else raise CalledProcessError
- # The idea of using `which` to check if a command is in PATH
- # originated from the Python mailing list.
- check_call(['which', executable])
- self._invalid_cmd_label.set_label('')
- except (ValueError, IndexError, CalledProcessError):
- self._invalid_cmd_label.set_label(_("<b>Command not found.</b>"))
- if data is '':
- self._invalid_cmd_label.set_label('')
-
- def _non_zero_duration(self):
- (hours, minutes, seconds) = self._duration_chooser.get_duration()
- return (hours > 0 or minutes > 0 or seconds > 0)
-
- def _check_for_valid_save_preset_input(self):
- self._save_button.props.sensitive = (self._non_zero_duration() and
- self._valid_name_func(self._name_entry.get_text()))
- # TODO: Add validator for next_timer_combo
-
- def _check_for_valid_start_timer_input(self):
- self._ok_button.props.sensitive = self._non_zero_duration()
-
- def _on_preset_button_clicked(self, button, row_path):
- self.emit('clicked-preset', row_path)
-
- def _on_preset_button_double_clicked(self, button, event, row_path):
- """Emit the `double-clicked-preset' signal."""
- # Check that the double-click event shot off on the preset button
- if event.type == gdk._2BUTTON_PRESS:
- self.emit('double-clicked-preset', row_path)
-
- def _on_manage_presets_button_clicked(self, button):
- self.emit('clicked-manage-presets')
-
- def _on_duration_changed(self, data=None):
- self._check_for_valid_start_timer_input()
- self._check_for_valid_save_preset_input()
-
- def _on_name_entry_changed(self, entry):
- self._check_for_valid_save_preset_input()
-
- def _on_dialog_response(self, dialog, response_id):
- if response_id == gtk.RESPONSE_OK:
- self._duration_chooser.normalize_fields()
- self.emit('clicked-start')
- elif response_id == gtk.RESPONSE_CANCEL:
- self.emit('clicked-cancel')
- self._dialog.hide()
-
- def _on_save_button_clicked(self, button):
- self._duration_chooser.normalize_fields()
- (hours, minutes, seconds) = self._duration_chooser.get_duration()
- name = self._name_entry.get_text()
- command = self._command_entry.get_text()
- next_timer = self._next_timer_combo.child.get_text()
- auto_start = self._auto_start_check.get_active()
- self.emit('clicked-save', name, hours, minutes, seconds, command,
- next_timer, auto_start)
-
- def _on_next_timer_combo_entry_child_changed(self, widget, data=None):
- """Validate selection of the Next Timer ComboBoxEntry."""
- modelfilter = self._presets_store.filter_new()
- # Loop through all rows in ListStore
- # TODO: Using a generator may be more memory efficient in this case.
- for row in modelfilter:
- # Check that name of preset is the exact match of the the text in
- # the ComboBoxEntry
- if widget.get_text() == row[0]:
- # Yes, it matches! Make the auto-start checkbox sensitive
- # (activate it).
- self._auto_start_check.set_sensitive(True)
- break
- else:
- # If value of ComboBoxEntry is None then de-activate the
- # auto-start checkbox.
- self._auto_start_check.set_sensitive(False)
-
diff --git a/timer-applet/src/timerapplet/ui/StatusButton.py b/timer-applet/src/timerapplet/ui/StatusButton.py
deleted file mode 100644
index 23e939ce..00000000
--- a/timer-applet/src/timerapplet/ui/StatusButton.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gtk
-from PulseButton import PulseButton
-from PieMeter import PieMeter
-
-class StatusButton(PulseButton):
- def __init__(self):
- PulseButton.__init__(self)
-
- self._tooltip = gtk.Tooltip()
-
- self._icon_widget = gtk.Image()
- self._pie_meter = PieMeter()
- self._label_widget = gtk.Label()
- self._visual_box = gtk.HBox()
-
- self._visual_box.pack_start(self._icon_widget)
- self._visual_box.pack_start(self._pie_meter)
-
- self._layout_box = None
- self._use_vertical = None
- self.set_use_vertical_layout(False)
-
- # _pie_meter will default to visible while
- # _icon_widget will default to hidden.
- self._pie_meter.show()
- self._visual_box.show()
- self._label_widget.show()
-
- def set_tooltip(self, tip_text):
- self._tooltip.set_text(tip_text)
-
- def set_label(self, text):
- self._label_widget.set_text(text)
-
- def set_icon(self, image_path):
- self._icon_widget.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(image_path, -1, 20))
- #elf._icon_widget.set_from_file(image_path)
-
- def set_use_icon(self, use_icon):
- if use_icon:
- self._pie_meter.hide()
- self._icon_widget.show()
- else:
- self._pie_meter.show()
- self._icon_widget.hide()
-
- def set_sensitized(self, sensitized):
- self._label_widget.props.sensitive = sensitized
-
- def set_show_remaining_time(self, show_remaining_time):
- if show_remaining_time:
- self._label_widget.show()
- else:
- self._label_widget.hide()
-
- def set_progress(self, progress):
- self._pie_meter.set_progress(progress)
-
- def set_use_vertical_layout(self, use_vertical):
- if self._use_vertical == use_vertical:
- return
-
- self._use_vertical = use_vertical
- if self._layout_box is not None:
- self._layout_box.remove(self._visual_box)
- self._layout_box.remove(self._label_widget)
- self.remove(self._layout_box)
- self._layout_box.destroy()
- self._layout_box = None
-
- new_layout_box = None
- if self._use_vertical:
- new_layout_box = gtk.VBox(False, 2)
- else:
- new_layout_box = gtk.HBox(False, 2)
-
- new_layout_box.pack_start(self._visual_box, True, True, 0)
- new_layout_box.pack_start(self._label_widget, False, False, 0)
-
- self._layout_box = new_layout_box
- self.add(self._layout_box)
- self._layout_box.show()
-
- def set_pie_fill_color(self, red, green, blue):
- self._pie_meter.set_fill_color(red, green, blue)
diff --git a/timer-applet/src/timerapplet/ui/__init__.py b/timer-applet/src/timerapplet/ui/__init__.py
deleted file mode 100644
index a0da1fa4..00000000
--- a/timer-applet/src/timerapplet/ui/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from AddEditPresetDialog import AddEditPresetDialog
-from ContinueTimerDialog import ContinueTimerDialog
-from DurationChooser import DurationChooser
-from ManagePresetsDialog import ManagePresetsDialog
-from Notifier import Notifier
-from PieMeter import PieMeter
-from PreferencesDialog import PreferencesDialog
-from PulseButton import PulseButton
-from ScrollableButtonList import ScrollableButtonList
-from StartTimerDialog import StartTimerDialog
-from StartNextTimerDialog import StartNextTimerDialog
-from StatusButton import StatusButton
diff --git a/timer-applet/src/timerapplet/utils.py b/timer-applet/src/timerapplet/utils.py
deleted file mode 100644
index 02113501..00000000
--- a/timer-applet/src/timerapplet/utils.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (C) 2008 Jimmy Do <[email protected]>
-# Copyright (C) 2010 Kenny Meyer <[email protected]>
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from gettext import gettext as _
-
-def is_valid_preset_name(name_str, preset_store, allowed_names=()):
- if len(name_str) == 0:
- return False
-
- name_str = name_str.lower()
- for allowed in allowed_names:
- if name_str == allowed.lower():
- return True
-
- return not preset_store.preset_name_exists_case_insensitive(name_str)
-
-def seconds_to_hms(total_seconds):
- (hours, remaining_seconds) = divmod(total_seconds, 3600)
- (minutes, seconds) = divmod(remaining_seconds, 60)
- return (hours, minutes, seconds)
-
-def hms_to_seconds(hours, minutes, seconds):
- return hours * 3600 + minutes * 60 + seconds
-
-def construct_time_str(remaining_seconds, show_all=True):
- """Return a user-friendly representation of remaining time based on the given number of seconds.
-
- show_all specifies whether the returned string should show all time components.
- If show_all is True (default), the returned string is in HH:MM:SS format.
- If show_all is False, the returned string is in either HH:MM or MM:SS format,
- depending on how much time is remaining. This avoids showing the user more
- information than necessary.
-
- """
- hours, minutes, seconds = seconds_to_hms(remaining_seconds)
- if show_all:
- # HH:MM:SS
- return _('%02d:%02d:%02d') % (hours, minutes, seconds)
- else:
- if hours > 0 or minutes > 14:
- # HH:MM
- return _('%02d:%02d') % (hours, minutes)
- else:
- # MM:SS
- return _('%02d:%02d') % (minutes, seconds)
-
-def get_display_text_from_datetime(date_time):
- return date_time.strftime('%X')
-
-def get_preset_display_text(presets_store, row_iter):
- (name, hours, minutes, seconds, command, next_timer, auto_start) = \
- presets_store.get_preset(row_iter)
-
- # <preset name> (HH:MM:SS)
- return _('%s (%02d:%02d:%02d)') % (name, hours, minutes, seconds)
-
-def serialize_bool(boolean):
- if boolean:
- return "1"
- return "0"
-
-def deserialize_bool(string):
- if string == "1":
- return True
- return False
diff --git a/timerapplet/Makefile.am b/timerapplet/Makefile.am
new file mode 100644
index 00000000..e0af8402
--- /dev/null
+++ b/timerapplet/Makefile.am
@@ -0,0 +1,45 @@
+AM_CPPFLAGS = \
+ $(MATE_APPLETS4_CFLAGS) \
+ $(LIBNOTIFY_CFLAGS) \
+ -I$(srcdir) \
+ -DMATELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+APPLET_LOCATION = $(libexecdir)/timer-applet
+
+libexec_PROGRAMS = timer-applet
+timer_applet_SOURCES = timerapplet.c
+timer_applet_LDADD = $(MATE_APPLETS4_LIBS) $(LIBNOTIFY_LIBS)
+timer_applet_CFLAGS = $(WARN_CFLAGS)
+
+appletsdir = $(datadir)/mate-panel/applets
+applets_in_files = org.mate.applets.TimerApplet.mate-panel-applet.in
+applets_DATA = $(applets_in_files:.mate-panel-applet.in=.mate-panel-applet)
+
+$(applets_in_files): $(applets_in_files).in Makefile
+ $(AM_V_GEN)sed \
+ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \
+ $< > $@
+%.mate-panel-applet: %.mate-panel-applet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.mate.panel.applet.TimerAppletFactory.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+org.mate.panel.applet.TimerAppletFactory.service: $(service_in_files)
+ $(AM_V_GEN)sed \
+ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \
+ $< > $@
+
+@INTLTOOL_XML_NOMERGE_RULE@
+gsettings_SCHEMAS = org.mate.panel.applet.timer.gschema.xml
+@GSETTINGS_RULES@
+
+%.gschema.xml.in: %.gschema.xml.in.in Makefile
+ $(AM_V_GEN) $(SED) -e 's^\@GETTEXT_PACKAGE\@^$(GETTEXT_PACKAGE)^g' < $< > $@
+
+EXTRA_DIST = \
+ $(applets_in_files) \
+ $(service_in_files) \
+ $(gsettings_SCHEMAS).in.in
+
diff --git a/timerapplet/org.mate.applets.TimerApplet.mate-panel-applet.in.in b/timerapplet/org.mate.applets.TimerApplet.mate-panel-applet.in.in
new file mode 100644
index 00000000..38a23a63
--- /dev/null
+++ b/timerapplet/org.mate.applets.TimerApplet.mate-panel-applet.in.in
@@ -0,0 +1,10 @@
+[Applet Factory]
+Id=TimerAppletFactory
+Location=@LOCATION@
+_Name=Timer Factory
+_Description=Timer Factory
+
+[TimerApplet]
+_Name=Timer
+_Description=Start a timer and receive a notification when it is finished
+Icon=time
diff --git a/timerapplet/org.mate.panel.applet.TimerAppletFactory.service.in b/timerapplet/org.mate.panel.applet.TimerAppletFactory.service.in
new file mode 100644
index 00000000..b8cd68cc
--- /dev/null
+++ b/timerapplet/org.mate.panel.applet.TimerAppletFactory.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.mate.panel.applet.TimerAppletFactory
+Exec=@LOCATION@
diff --git a/timerapplet/org.mate.panel.applet.timer.gschema.xml.in.in b/timerapplet/org.mate.panel.applet.timer.gschema.xml.in.in
new file mode 100644
index 00000000..8e2b40b9
--- /dev/null
+++ b/timerapplet/org.mate.panel.applet.timer.gschema.xml.in.in
@@ -0,0 +1,20 @@
+<schemalist gettext-domain="@GETTEXT_PACKAGE@">
+ <schema id="org.mate.panel.applet.timer">
+ <key name="name" type="s">
+ <default>'Timer'</default>
+ <_summary>Name of timer</_summary>
+ </key>
+ <key name="duration" type="i">
+ <default>10</default>
+ <_summary>Duration of timer in seconds</_summary>
+ </key>
+ <key name="show-notification" type="b">
+ <default>true</default>
+ <_summary>Show notification popup when timer finish</_summary>
+ </key>
+ <key name="show-dialog" type="b">
+ <default>false</default>
+ <_summary>Show dialog window when timer finish</_summary>
+ </key>
+ </schema>
+</schemalist>
diff --git a/timerapplet/timerapplet.c b/timerapplet/timerapplet.c
new file mode 100644
index 00000000..8e64c14f
--- /dev/null
+++ b/timerapplet/timerapplet.c
@@ -0,0 +1,448 @@
+/* timerapplet.c:
+ *
+ * Copyright (C) 2014 Stefano Karapetsas
+ *
+ * This file is part of MATE Applets.
+ *
+ * MATE Applets 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.
+ *
+ * MATE Applets 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 MATE Applets. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Stefano Karapetsas <[email protected]>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include <libnotify/notify.h>
+
+#include <mate-panel-applet.h>
+#include <mate-panel-applet-gsettings.h>
+
+/* Applet constants */
+#define APPLET_ICON "time"
+#define STEP 100
+
+/* GSettings constants */
+#define TIMER_SCHEMA "org.mate.panel.applet.timer"
+#define NAME_KEY "name"
+#define DURATION_KEY "duration"
+#define SHOW_NOTIFICATION_KEY "show-notification"
+#define SHOW_DIALOG_KEY "show-dialog"
+
+typedef struct
+{
+ MatePanelApplet *applet;
+
+ GSettings *settings;
+
+ GtkActionGroup *action_group;
+ GtkLabel *label;
+ GtkImage *image;
+ GtkImage *pause_image;
+ GtkHBox *hbox;
+
+ GtkSpinButton *hours;
+ GtkSpinButton *minutes;
+ GtkSpinButton *seconds;
+
+ gboolean active;
+ gboolean pause;
+ gint elapsed;
+
+ guint timeout_id;
+} TimerApplet;
+
+static void timer_start_callback (GtkAction *action, TimerApplet *applet);
+static void timer_pause_callback (GtkAction *action, TimerApplet *applet);
+static void timer_stop_callback (GtkAction *action, TimerApplet *applet);
+static void timer_about_callback (GtkAction *action, TimerApplet *applet);
+static void timer_preferences_callback (GtkAction *action, TimerApplet *applet);
+
+static const GtkActionEntry applet_menu_actions [] = {
+ { "Start", GTK_STOCK_MEDIA_PLAY, N_("_Start timer"), NULL, NULL, G_CALLBACK (timer_start_callback) },
+ { "Pause", GTK_STOCK_MEDIA_PAUSE, N_("P_ause timer"), NULL, NULL, G_CALLBACK (timer_pause_callback) },
+ { "Stop", GTK_STOCK_MEDIA_STOP, N_("S_top timer"), NULL, NULL, G_CALLBACK (timer_stop_callback) },
+ { "Preferences", GTK_STOCK_PROPERTIES, N_("_Preferences"), NULL, NULL, G_CALLBACK (timer_preferences_callback) },
+ { "About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, G_CALLBACK (timer_about_callback) }
+};
+
+static char *ui = "<menuitem name='Item 1' action='Start' />"
+ "<menuitem name='Item 2' action='Pause' />"
+ "<menuitem name='Item 3' action='Stop' />"
+ "<menuitem name='Item 4' action='Preferences' />"
+ "<menuitem name='Item 5' action='About' />";
+
+static void
+timer_applet_destroy (MatePanelApplet *applet_widget, TimerApplet *applet)
+{
+ g_assert (applet);
+
+ if (applet->timeout_id != 0)
+ {
+ g_source_remove(applet->timeout_id);
+ applet->timeout_id = 0;
+ }
+
+ g_object_unref (applet->settings);
+
+ notify_uninit ();
+}
+
+/* timer management */
+static gboolean
+timer_callback (TimerApplet *applet)
+{
+ gboolean retval = TRUE;
+ gchar *label;
+ gchar *name;
+ gchar *tooltip;
+ gint hours, minutes, seconds, duration, remaining;
+
+ label = NULL;
+ name = NULL;
+ tooltip = NULL;
+
+ if (!applet->active)
+ {
+ gtk_label_set_text (applet->label, "");
+ gtk_widget_set_tooltip_text (GTK_WIDGET (applet->label), "");
+ gtk_widget_hide (GTK_WIDGET (applet->pause_image));
+ }
+ else
+ {
+ if (applet->active && !applet->pause)
+ applet->elapsed += STEP;
+
+ duration = g_settings_get_int (applet->settings, DURATION_KEY);
+ name = g_settings_get_string (applet->settings, NAME_KEY);
+
+ remaining = duration - (applet->elapsed / 1000);
+
+ if (remaining <= 0)
+ {
+ applet->active = FALSE;
+ gtk_label_set_text (applet->label, _("Finished"));
+ gtk_widget_set_tooltip_text (GTK_WIDGET (applet->label), name);
+ gtk_widget_hide (GTK_WIDGET (applet->pause_image));
+
+ if (g_settings_get_boolean (applet->settings, SHOW_NOTIFICATION_KEY))
+ {
+ NotifyNotification *n;
+ n = notify_notification_new (name, _("Timer finished!"), "time");
+ notify_notification_set_timeout (n, 30000);
+ notify_notification_show (n, NULL);
+ g_object_unref (G_OBJECT (n));
+ }
+
+ if (g_settings_get_boolean (applet->settings, SHOW_DIALOG_KEY))
+ {
+ GtkWidget *dialog = gtk_message_dialog_new_with_markup (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ "<b>%s</b>\n\n%s", name, _("Timer finished!"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+
+ /* stop further calls */
+ retval = FALSE;
+ }
+ else
+ {
+ hours = remaining / 60 / 60;
+ minutes = remaining / 60 % 60;
+ seconds = remaining % 60;
+
+ if (hours > 0)
+ label = g_strdup_printf ("%02d:%02d:%02d", hours, minutes, seconds);
+ else
+ label = g_strdup_printf ("%02d:%02d", minutes, seconds);
+
+ hours = duration / 60 / 60;
+ minutes = duration / 60 % 60;
+ seconds = duration % 60;
+
+ if (hours > 0)
+ tooltip = g_strdup_printf ("%s (%02d:%02d:%02d)", name, hours, minutes, seconds);
+ else
+ tooltip = g_strdup_printf ("%s (%02d:%02d)", name, minutes, seconds);
+
+ gtk_label_set_text (applet->label, label);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (applet->label), tooltip);
+ gtk_widget_set_visible (GTK_WIDGET (applet->pause_image), applet->pause);
+ }
+
+ g_free (label);
+ g_free (name);
+ g_free (tooltip);
+ }
+
+ /* update actions sensitiveness */
+ gtk_action_set_sensitive (gtk_action_group_get_action (applet->action_group, "Start"), !applet->active || applet->pause);
+ gtk_action_set_sensitive (gtk_action_group_get_action (applet->action_group, "Pause"), applet->active && !applet->pause);
+ gtk_action_set_sensitive (gtk_action_group_get_action (applet->action_group, "Stop"), applet->active);
+ gtk_action_set_sensitive (gtk_action_group_get_action (applet->action_group, "Preferences"), !applet->active && !applet->pause);
+
+ return retval;
+}
+
+/* start action */
+static void
+timer_start_callback (GtkAction *action, TimerApplet *applet)
+{
+ applet->active = TRUE;
+ if (applet->pause)
+ applet->pause = FALSE;
+ else
+ applet->elapsed = 0;
+ applet->timeout_id = g_timeout_add (STEP, (GSourceFunc) timer_callback, applet);
+}
+
+/* pause action */
+static void
+timer_pause_callback (GtkAction *action, TimerApplet *applet)
+{
+ applet->pause = TRUE;
+ if (applet->timeout_id != 0)
+ {
+ g_source_remove(applet->timeout_id);
+ applet->timeout_id = 0;
+ }
+ timer_callback (applet);
+}
+
+/* stop action */
+static void
+timer_stop_callback (GtkAction *action, TimerApplet *applet)
+{
+ applet->active = FALSE;
+ if (applet->timeout_id != 0)
+ {
+ g_source_remove(applet->timeout_id);
+ applet->timeout_id = 0;
+ }
+ timer_callback (applet);
+}
+
+/* Show the about dialog */
+static void
+timer_about_callback (GtkAction *action, TimerApplet *applet)
+{
+ const char* authors[] = { "Stefano Karapetsas <[email protected]>", NULL };
+
+ gtk_show_about_dialog(NULL,
+ "version", VERSION,
+ "copyright", "Copyright © 2014 Stefano Karapetsas",
+ "authors", authors,
+ "comments", _("Start a timer and receive a notification when it is finished"),
+ "translator-credits", _("translator-credits"),
+ "logo-icon-name", APPLET_ICON,
+ NULL);
+}
+
+/* calculate duration and save in GSettings */
+static void
+timer_spin_button_value_changed (GtkSpinButton *spinbutton, TimerApplet *applet)
+{
+ gint duration = 0;
+
+ duration += gtk_spin_button_get_value (applet->hours) * 60 * 60;
+ duration += gtk_spin_button_get_value (applet->minutes) * 60;
+ duration += gtk_spin_button_get_value (applet->seconds);
+
+ g_settings_set_int (applet->settings, DURATION_KEY, duration);
+}
+
+/* Show the preferences dialog */
+static void
+timer_preferences_callback (GtkAction *action, TimerApplet *applet)
+{
+ GtkDialog *dialog;
+ GtkTable *table;
+ GtkWidget *widget;
+ gint duration, hours, minutes, seconds;
+
+ duration = g_settings_get_int (applet->settings, DURATION_KEY);
+ hours = duration / 60 / 60;
+ minutes = duration / 60 % 60;
+ seconds = duration % 60;
+
+ dialog = GTK_DIALOG (gtk_dialog_new_with_buttons(_("Timer Applet Preferences"),
+ NULL,
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL));
+ table = gtk_table_new (6, 2, FALSE);
+ gtk_table_set_row_spacings (table, 12);
+ gtk_table_set_col_spacings (table, 12);
+
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 350, 150);
+
+ widget = gtk_label_new (_("Name:"));
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_table_attach (table, widget, 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ widget = gtk_entry_new ();
+ gtk_table_attach (table, widget, 2, 3, 0, 1,
+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL,
+ 0, 0);
+ g_settings_bind (applet->settings, NAME_KEY, widget, "text", G_SETTINGS_BIND_DEFAULT);
+
+ widget = gtk_label_new (_("Hours:"));
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_table_attach (table, widget, 1, 2, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ widget = gtk_spin_button_new_with_range (0.0, 100.0, 1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), hours);
+ gtk_table_attach (table, widget, 2, 3, 1, 2,
+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL,
+ 0, 0);
+ applet->hours = GTK_SPIN_BUTTON (widget);
+ g_signal_connect (widget, "value-changed", G_CALLBACK (timer_spin_button_value_changed), applet);
+
+ widget = gtk_label_new (_("Minutes:"));
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_table_attach (table, widget, 1, 2, 2, 3,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ widget = gtk_spin_button_new_with_range (0.0, 59.0, 1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), minutes);
+ gtk_table_attach (table, widget, 2, 3, 2, 3,
+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL,
+ 0, 0);
+ applet->minutes = GTK_SPIN_BUTTON (widget);
+ g_signal_connect (widget, "value-changed", G_CALLBACK (timer_spin_button_value_changed), applet);
+
+ widget = gtk_label_new (_("Seconds:"));
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_table_attach (table, widget, 1, 2, 3, 4,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ widget = gtk_spin_button_new_with_range (0.0, 59.0, 1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), seconds);
+ gtk_table_attach (table, widget, 2, 3, 3, 4,
+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL,
+ 0, 0);
+ applet->seconds = GTK_SPIN_BUTTON (widget);
+ g_signal_connect (widget, "value-changed", G_CALLBACK (timer_spin_button_value_changed), applet);
+
+ widget = gtk_check_button_new_with_label (_("Show notification popup"));
+ gtk_table_attach (table, widget, 2, 3, 4, 5,
+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL,
+ 0, 0);
+ g_settings_bind (applet->settings, SHOW_NOTIFICATION_KEY, widget, "active", G_SETTINGS_BIND_DEFAULT);
+
+ widget = gtk_check_button_new_with_label (_("Show dialog"));
+ gtk_table_attach (table, widget, 2, 3, 5, 6,
+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL,
+ 0, 0);
+ g_settings_bind (applet->settings, SHOW_DIALOG_KEY, widget, "active", G_SETTINGS_BIND_DEFAULT);
+
+ gtk_box_pack_start_defaults (GTK_BOX (dialog->vbox), GTK_WIDGET (table));
+
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
+
+ gtk_widget_show_all (GTK_WIDGET (dialog));
+}
+
+static gboolean
+timer_applet_fill (MatePanelApplet* applet_widget)
+{
+ TimerApplet *applet;
+
+ g_set_application_name (_("Timer Applet"));
+ gtk_window_set_default_icon_name (APPLET_ICON);
+
+ if (!notify_is_initted ())
+ notify_init ("timer-applet");
+
+ mate_panel_applet_set_flags (applet_widget, MATE_PANEL_APPLET_EXPAND_MINOR);
+ mate_panel_applet_set_background_widget (applet_widget, GTK_WIDGET (applet));
+
+ applet = g_malloc0(sizeof(TimerApplet));
+ applet->applet = applet_widget;
+ applet->settings = mate_panel_applet_settings_new (applet_widget,TIMER_SCHEMA);
+ applet->timeout_id = 0;
+ applet->active = FALSE;
+ applet->pause = FALSE;
+
+ applet->hbox = GTK_HBOX (gtk_hbox_new (FALSE, 0));
+ applet->image = GTK_IMAGE (gtk_image_new_from_icon_name (APPLET_ICON, GTK_ICON_SIZE_BUTTON));
+ applet->pause_image = GTK_IMAGE (gtk_image_new_from_icon_name (GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_BUTTON));
+ applet->label = GTK_LABEL (gtk_label_new (""));
+
+ /* we add the Gtk label into the applet */
+ gtk_box_pack_start (GTK_BOX (applet->hbox),
+ GTK_WIDGET (applet->image),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (applet->hbox),
+ GTK_WIDGET (applet->pause_image),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (applet->hbox),
+ GTK_WIDGET (applet->label),
+ TRUE, TRUE, 3);
+
+ gtk_container_add (GTK_CONTAINER (applet_widget),
+ GTK_WIDGET (applet->hbox));
+
+ gtk_widget_show_all (GTK_WIDGET (applet->applet));
+ gtk_widget_hide (GTK_WIDGET (applet->pause_image));
+
+ g_signal_connect(G_OBJECT (applet->applet), "destroy",
+ G_CALLBACK (timer_applet_destroy),
+ applet);
+
+ /* set up context menu */
+ applet->action_group = gtk_action_group_new ("Timer Applet Actions");
+ gtk_action_group_set_translation_domain (applet->action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (applet->action_group, applet_menu_actions,
+ G_N_ELEMENTS (applet_menu_actions), applet);
+ mate_panel_applet_setup_menu (applet->applet, ui, applet->action_group);
+
+ /* execute callback to set actions sensitiveness */
+ timer_callback (applet);
+
+ return TRUE;
+}
+
+/* this function, called by mate-panel, will create the applet */
+static gboolean
+timer_factory (MatePanelApplet* applet, const char* iid, gpointer data)
+{
+ gboolean retval = FALSE;
+
+ if (!g_strcmp0 (iid, "TimerApplet"))
+ retval = timer_applet_fill (applet);
+
+ return retval;
+}
+
+/* needed by mate-panel applet library */
+MATE_PANEL_APPLET_OUT_PROCESS_FACTORY("TimerAppletFactory",
+ PANEL_TYPE_APPLET,
+ "Timer applet",
+ timer_factory,
+ NULL)