Browse Source

smd-applet ported to recent GNOME technology

- only 2 windows: main and error
- reworked configuration tab using GtkSwitch
- main tab includes the old "pause" control and the "log" dialog
  - log dialog automatically updated every 2 seconds
- status icon has no menu, it just pops up the window when activated
- missing configuration notification has now a button to pop up the
  configuration tab
- the "quit" control is in the gnome-shell top bar now
Enrico Tassi 6 years ago
parent
commit
a7a556f776
5 changed files with 760 additions and 597 deletions
  1. 1
    1
      Makefile
  2. 1
    2
      smd-applet.1.txt
  3. 622
    422
      smd-applet.ui
  4. 136
    162
      smd-applet.vala
  5. 0
    10
      xdg/applications/smd-applet-configure.desktop

+ 1
- 1
Makefile View File

@@ -29,7 +29,7 @@ PKGS_VALA=glib-2.0 $(PKG_GTK) libnotify gconf-2.0 gee-1.0 gio-2.0
29 29
 TARGET_GLIB=2.32
30 30
 PKGCONFIG_CHECK_GLIB_VERSION=--atleast-version=$(TARGET_GLIB) glib-2.0
31 31
 PKGCONFIG_GLIB_VERSION=--modversion glib-2.0
32
-VALAC=valac-0.20
32
+VALAC=valac-0.22
33 33
 H=@
34 34
 
35 35
 # ----------------------------------------------------------------------------

+ 1
- 2
smd-applet.1.txt View File

@@ -2,7 +2,7 @@ NAME
2 2
   smd-applet - graphical interface for smd-pull
3 3
 
4 4
 SYNOPSIS
5
-  smd-applet [-cvl]
5
+  smd-applet [-vl]
6 6
 
7 7
 DESCRIPTION
8 8
   smd-applet is an applet for the GNOME notification area, that runs smd-loop,
@@ -10,7 +10,6 @@ DESCRIPTION
10 10
   suggested commands by clicking on buttons instead of using a terminal.
11 11
 
12 12
 OPTIONS
13
-  -c, --configure            Do not run smd-loop, just open the configuration window
14 13
   -v, --verbose              Increase program verbosity, debugging only
15 14
   -l, --smd-loop=command     override smd-loop command name, debugging only
16 15
 

+ 622
- 422
smd-applet.ui
File diff suppressed because it is too large
View File


+ 136
- 162
smd-applet.vala View File

@@ -113,12 +113,11 @@ static string SMD_PP_DEF_CFG;
113 113
 static string XDG_AUTORUN_FILE;
114 114
 
115 115
 // the main class containing all the data smd-applet will use
116
-class smdApplet {
116
+class smdApplet : Gtk.Application {
117 117
 
118 118
 	// =================== the constants ===============================
119 119
 
120 120
 	// settings keys
121
-	static const string key_icon    = "icon-only-on-errors";
122 121
 	static const string key_newmail = "notify-new-mail";
123 122
 
124 123
 	// paths, set by main() to something that depends on the 
@@ -134,14 +133,11 @@ class smdApplet {
134 133
 	Gtk.Builder builder = null;
135 134
 
136 135
 	// main widgets
137
-	Gtk.Menu menuL = null;
138
-	Gtk.Menu menuR = null;
139 136
 	Gtk.StatusIcon si = null;
140 137
 	Gtk.Window win = null;
141 138
 	Gtk.Window err_win = null;
142
-	Gtk.Window log_win = null;
143
-	Gtk.AboutDialog about_win = null;
144
-	Gtk.CheckMenuItem miPause = null;
139
+	Gtk.Notebook notebook = null;
140
+	Gtk.Switch sync_active = null;
145 141
 
146 142
 	// Stuff for logs display
147 143
 	Gtk.ComboBoxText cblogs = null;
@@ -174,11 +170,27 @@ class smdApplet {
174 170
 	Notify.Notification notification = null;
175 171
 	bool notification_server_has_persistence = false;
176 172
 
173
+	static string menu_ui = """
174
+	<interface>
175
+	  <menu id='app-menu'>
176
+	    <section>
177
+	      <item>
178
+	        <attribute name='label' translatable='yes'>_Quit</attribute>
179
+	        <attribute name='action'>app.quit</attribute>
180
+	      </item>
181
+	    </section>
182
+	  </menu>
183
+	</interface>
184
+	""";
177 185
 
178 186
 	// ======================= constructor ================================
179 187
 
180 188
 	// initialize data structures and build gtk+ widgets
181
-	public smdApplet(bool hide_status_icon) throws Exit {
189
+	public smdApplet() throws Exit {
190
+		set_application_id("org.syncmaildir");
191
+		try { register(); }
192
+		catch (GLib.Error e) { stderr.printf("%s\n",e.message); };
193
+
182 194
 		// load the ui file
183 195
 		builder = new Gtk.Builder ();
184 196
 		try { builder.add_from_file (smd_applet_ui); } 
@@ -186,6 +198,11 @@ class smdApplet {
186 198
 			stderr.printf("%s\n",e.message); 
187 199
 			throw new Exit.ABORT("Unable to load the ui file");
188 200
 		}
201
+		try { builder.add_from_string (menu_ui, menu_ui.length); } 
202
+		catch (GLib.Error e) { 
203
+			stderr.printf("%s\n",e.message); 
204
+			throw new Exit.ABORT("Unable to load the menu ui string");
205
+		}
189 206
 	
190 207
 		// events queue and mutex
191 208
 		events = new Gee.ArrayList<Event>();
@@ -197,8 +214,8 @@ class smdApplet {
197 214
 		try {
198 215
 			net_manager=Bus.get_proxy_sync(BusType.SYSTEM,NM_SERVICE,NM_PATH);
199 216
 	        net_manager.state_changed.connect((s) => {
200
-				if (is_nm_connected(s)) miPause.set_active(false);
201
-				else miPause.set_active(true);
217
+				if (is_nm_connected(s)) sync_active.set_active(true);
218
+				else sync_active.set_active(false);
202 219
 			});
203 220
 		} catch (GLib.Error e) {
204 221
 			stderr.printf("%s\n",e.message);
@@ -206,60 +223,30 @@ class smdApplet {
206 223
 		}
207 224
 
208 225
 		// load widgets and attach callbacks
209
-		win = builder.get_object("wPrefs") as Gtk.Window;
226
+		var simple_mainwin = builder.get_object("wMain") as Gtk.Window;
227
+		win = new Gtk.ApplicationWindow(this);
228
+		simple_mainwin.get_child().reparent(win);
229
+		var w = 0;
230
+		var h = 0;
231
+		simple_mainwin.get_size_request(out w, out h);
232
+		win.set_size_request(w,h);
233
+		win.set_title(simple_mainwin.get_title());
210 234
 		err_win = builder.get_object("wError") as Gtk.Window;
211
-		about_win = builder.get_object("wAbout") as Gtk.AboutDialog;
212
-		about_win.set_copyright("Copyright " + SMDConf.COPYRIGHT);
213
-		log_win = builder.get_object("wLog") as Gtk.Window;
235
+		var lcopyright = builder.get_object("lCopyright") as Gtk.Label;
236
+		lcopyright.set_text("Copyright " + SMDConf.COPYRIGHT);
214 237
 		var logs_vb = builder.get_object("vbLog") as Gtk.Grid;
215 238
 		cblogs = new Gtk.ComboBoxText();
216 239
 		lognames = new Gee.ArrayList<string>();
217 240
 		logs_vb.attach(cblogs,0,0,1,1);
218 241
 		cblogs.show();
219
-		cblogs.changed.connect((cb) => {
220
-			int selected = cblogs.get_active();
221
-			if (selected >= 0) {
222
-				string file = lognames.get(selected);
223
-				string content;
224
-				try {
225
-					if (GLib.FileUtils.get_contents(
226
-							SMD_LOGS_DIR+file,out content)){
227
-						var tv = builder.get_object("tvLog") as Gtk.TextView;
228
-						var b = tv.get_buffer();
229
-						b.set_text(content,-1);
230
-						Gtk.TextIter end_iter;
231
-						b.get_end_iter(out end_iter);
232
-						var end_mark = b.create_mark("end",end_iter,false);
233
-						tv.scroll_to_mark(end_mark, 0.0, true, 0.0, 0.0);
234
-					} else {
235
-						stderr.printf("Unable to read %s\n",SMD_LOGS_DIR+file);
236
-					}
237
-				} catch (GLib.FileError e) { 
238
-						stderr.printf("Unable to read %s: %s\n",
239
-							SMD_LOGS_DIR+file, e.message);
240
-				}
241
-			}
242
-		});
243
-
244
-		var close_log = builder.get_object("bLogClose") as Gtk.Button;
245
-		close_log.clicked.connect(close_logs_action);
246
-		log_win.delete_event.connect(close_logs_event);
247
-
248
-		var close = builder.get_object("bClosePrefs") as Gtk.Button;
249
-		close.clicked.connect(close_prefs_action);
242
+		update_logcontents();
250 243
 
251
-		var bicon = builder.get_object("cbIcon") as Gtk.CheckButton;
252
-		bicon.set_active( settings.get_boolean(key_icon));
253
-		bicon.toggled.connect((b) => {
254
-			settings.set_boolean(key_icon,b.active); 
255
-			si.set_visible(!settings.get_boolean(key_icon));
256
-		});
257
-		var bnotify = builder.get_object("cbNotify") as Gtk.CheckButton;
244
+		var bnotify = builder.get_object("sNotify") as Gtk.Switch;
258 245
 		bnotify.set_active(settings.get_boolean(key_newmail));
259
-		bnotify.toggled.connect((b) => {
260
-			settings.set_boolean(key_newmail,b.active);
246
+		bnotify.notify["active"].connect(() => {
247
+			settings.set_boolean(key_newmail,bnotify.active);
261 248
 		});
262
-		var bautostart = builder.get_object("cbAutostart") as Gtk.CheckButton;
249
+		var bautostart = builder.get_object("sAutostart") as Gtk.Switch;
263 250
 		try { string content;
264 251
 		  if (GLib.FileUtils.get_contents(XDG_AUTORUN_FILE,out content)){
265 252
 			if (GLib.Regex.match_simple(GNOME_AUTOSTART_DISABLED,content))
@@ -267,8 +254,8 @@ class smdApplet {
267 254
 			else bautostart.set_active(true);
268 255
 		  } else bautostart.set_active(false);
269 256
 		} catch (FileError e) { stderr.printf("%s\n",e.message); }
270
-		bautostart.toggled.connect((b) => {
271
-			if (b.active) {
257
+		bautostart.notify["active"].connect(() => {
258
+			if (bautostart.active) {
272 259
 				string content;
273 260
 				try {
274 261
 					GLib.FileUtils.get_contents(smd_applet_desktop,out content);
@@ -313,51 +300,44 @@ class smdApplet {
313 300
 		});
314 301
 
315 302
 		// menu popped up when the user clicks on the notification area
316
-        menuL = builder.get_object ("mLeft") as Gtk.Menu;
317
-        menuR = builder.get_object ("mRight") as Gtk.Menu;
318
-		var quit = builder.get_object ("miQuit") as Gtk.MenuItem;
319
-		quit.activate.connect((b) => { 
320
-			thread_die = true;
321
-			if ((int)pid != 0) {
322
-				debug("sending SIGTERM to %d".printf(-(int)pid));
323
-				Posix.kill((Posix.pid_t)(-(int)pid),Posix.SIGTERM);
324
-			}
325
-			Gtk.main_quit(); 
326
-		});
327
-		miPause = builder.get_object("miPause") as Gtk.CheckMenuItem;
328
-		miPause.toggled.connect((b) => {
329
-			if (miPause.get_active()) pause();
330
-			else unpause(); 
331
-		});
332
-		var about = builder.get_object ("miAbout") as Gtk.MenuItem;
333
-		about_win.response.connect((id) => { about_win.hide(); });
334
-		about.activate.connect((b) => { about_win.run(); });
335
-		about_win.set_comments("GNOME applet for syncmaildir version " + 
336
-			SMDConf.VERSION);
337
-		var prefs = builder.get_object ("miPrefs") as Gtk.MenuItem;
338
-		prefs.activate.connect((b) => {  win.show(); });
339
-		var logs = builder.get_object ("miLog") as Gtk.MenuItem;
340
-		logs.activate.connect((b) => { 
341
-			update_loglist();
342
-			log_win.show(); 
303
+		sync_active = builder.get_object("sSyncActive") as Gtk.Switch;
304
+		sync_active.notify["active"].connect(() => {
305
+			if (sync_active.get_active()) unpause();
306
+			else pause(); 
343 307
 		});
308
+		notebook = builder.get_object("nMain") as Gtk.Notebook;
309
+		update_loglist();
310
+		GLib.Timeout.add(2000,(() => {
311
+			update_loglist(); update_logcontents(); return true; }));
344 312
 
345 313
 		// status icon
346 314
 		si = new Gtk.StatusIcon.from_icon_name("mail-send-receive");
347
-		si.set_visible(!hide_status_icon);
315
+		si.set_visible(true);
348 316
 		si.set_tooltip_text("smd-applet is running");
349
-		si.popup_menu.connect((button,time) => {
350
-				menuR.popup(null,null,si.position_menu,0,
351
-					Gtk.get_current_event_time());
352
-		});
353 317
 		si.activate.connect((s) => { 
354 318
 			if ( error_mode ) 
355 319
 				err_win.reshow_with_initial_size();
356
-			else if( config_wait_mode )
320
+			else {
357 321
 				win.show();
358
-			else
359
-				menuL.popup(null,null,si.position_menu,0,
360
-					Gtk.get_current_event_time());
322
+				if ( config_wait_mode ) notebook.page = 1;
323
+				else notebook.page = 0;
324
+			}
325
+		});
326
+		
327
+		add_window(win);
328
+		activate.connect(() => { });
329
+
330
+		var quit = new SimpleAction("quit", null);
331
+		var menu = builder.get_object("app-menu") as MenuModel;
332
+		set_app_menu(menu);
333
+		add_action(quit);
334
+		quit.activate.connect(() => { 
335
+			thread_die = true;
336
+			if ((int)pid != 0) {
337
+				debug("sending SIGTERM to %d".printf(-(int)pid));
338
+				Posix.kill((Posix.pid_t)(-(int)pid),Posix.SIGTERM);
339
+			}
340
+			this.quit(); 
361 341
 		});
362 342
 
363 343
 		// notification system
@@ -389,7 +369,8 @@ class smdApplet {
389 369
 		// if no network, we do not start the thread and enter pause mode
390 370
 		// immediately
391 371
 		if (!force && net_manager != null && !is_nm_connected(net_manager.state)) {
392
-			miPause.set_active(true);
372
+			sync_active.set_active(false);
373
+			si.set_from_stock("gtk-media-pause");
393 374
 		} else {
394 375
 			// the thread fills the event queue
395 376
 			thread = new GLib.Thread<void *>(null, smdThread);
@@ -435,7 +416,7 @@ class smdApplet {
435 416
 		string permissions = null;
436 417
 		string mail_name = null;
437 418
 		string mail_body = null;
438
-		var commands = new Gee.ArrayList<string>();
419
+		var commands = new Gee.ArrayList<string>(str_equal);
439 420
 
440 421
 		if (has_actions) {
441 422
 			string acts = i_act.fetch(1);
@@ -770,16 +751,14 @@ class smdApplet {
770 751
 		error_mode = false;
771 752
 		si.set_tooltip_text("smd-applet is running");
772 753
 		si.set_from_icon_name("mail-send-receive");
773
-		si.set_visible(!settings.get_boolean(key_icon));
774 754
 		debug("joining smdThread");
775
-		thread.join();
755
+		if (thread != null) thread.join();
776 756
 		thread_die = false;
777 757
 		debug("starting smdThread");
778 758
 		start_smdThread(force);
779 759
 	}
780 760
 	
781 761
 	// these are just wrappers for close_prefs
782
-	private void close_prefs_action(Gtk.Button b){ close_prefs(); }
783 762
 	private bool close_prefs_event(Gdk.EventAny e){
784 763
 		close_prefs();
785 764
 		return true;
@@ -792,7 +771,6 @@ class smdApplet {
792 771
 		if (is_smd_stack_configured() && config_wait_mode) {
793 772
 			config_wait_mode = false;
794 773
 			// restore the default icon
795
-			si.set_visible(!settings.get_boolean(key_icon));
796 774
 			si.set_from_icon_name("mail-send-receive");
797 775
 
798 776
 			// start the thread (if connected)
@@ -801,24 +779,6 @@ class smdApplet {
801 779
 		}
802 780
 	}
803 781
 
804
-	// close logs win
805
-	private void close_logs(){ log_win.hide(); }
806
-
807
-	// these are just wrappers for close_logs
808
-	private void close_logs_action(Gtk.Button b){ close_logs(); }
809
-	private bool close_logs_event(Gdk.EventAny e){
810
-		close_logs();
811
-		return true;
812
-	}
813
-
814
-	// these are names for gtk_main_quit(), they are needed
815
-	// in order to remove signal handlers
816
-	private void my_gtk_main_quit_button(Gtk.Button b) { Gtk.main_quit(); }
817
-	private bool my_gtk_main_quit_event(Gdk.EventAny b) {
818
-		Gtk.main_quit();
819
-		return false;
820
-	}
821
-
822 782
 	// pause/unpause the program
823 783
 	private void pause() {
824 784
 		debug("enter pause mode");
@@ -840,7 +800,7 @@ class smdApplet {
840 800
 
841 801
     private bool is_smd_loop_configured() {
842 802
 		bool rc = GLib.FileUtils.test(SMD_LOOP_CFG,GLib.FileTest.EXISTS);
843
-		Gtk.Label l = builder.get_object("lErrLoop") as Gtk.Label;
803
+		var l = builder.get_object("bErrLoop") as Gtk.Box;
844 804
 		if (!rc) l.show();
845 805
 		else l.hide();
846 806
 		return rc;
@@ -848,7 +808,7 @@ class smdApplet {
848 808
 
849 809
     private bool is_smd_pushpull_configured() {
850 810
 		bool rc = GLib.FileUtils.test(SMD_PP_DEF_CFG,GLib.FileTest.EXISTS);
851
-		Gtk.Label l = builder.get_object("lErrPushPull") as Gtk.Label;
811
+		var l = builder.get_object("bErrPushPull") as Gtk.Box;
852 812
 		if (!rc) l.show();
853 813
 		else l.hide();
854 814
 		return rc;
@@ -869,30 +829,67 @@ class smdApplet {
869 829
 		try {
870 830
 			Dir d = GLib.Dir.open(SMD_LOGS_DIR);
871 831
 			string file;
872
-
873
-			((Gtk.ListStore)cblogs.get_model()).clear();
874
-			lognames.clear();
875
-
832
+			var new_lognames = new Gee.ArrayList<string>(str_equal);
833
+			
876 834
 			while ( (file = d.read_name()) != null ){
877
-				lognames.add(file);
878
-				cblogs.append_text(file);
835
+				new_lognames.add(file);
879 836
 			}
837
+
838
+			if (!new_lognames.contains_all(lognames) ||
839
+                !lognames.contains_all(new_lognames)) {
840
+
841
+				((Gtk.ListStore)cblogs.get_model()).clear();
842
+				lognames.clear();
843
+
844
+				foreach (string f in new_lognames) {
845
+					lognames.add(f);
846
+					cblogs.append_text(f);
847
+				}
880 848
 	
881
-			if (lognames.size == 0) {
882
-				b.set_text("No logs in %s".printf(SMD_LOGS_DIR),-1);
883
-			} else {
884
-				cblogs.set_title("Choose log file");
885
-				cblogs.set_active(0);
849
+				if (lognames.size == 0) {
850
+					b.set_text("No logs in %s".printf(SMD_LOGS_DIR),-1);
851
+				} else {
852
+					cblogs.set_title("Choose log file");
853
+					cblogs.set_active(0);
854
+				}
886 855
 			}
887 856
 		} catch (GLib.FileError e) {
888 857
 			b.set_text("Unable to list directory %s".printf(SMD_LOGS_DIR),-1);
889 858
 		}
890 859
 	}
891 860
 
861
+	void update_logcontents() {
862
+		int selected = cblogs.get_active();
863
+		if (selected >= 0) {
864
+			string file = lognames.get(selected);
865
+			string content;
866
+			try {
867
+				if (GLib.FileUtils.get_contents(
868
+						SMD_LOGS_DIR+file,out content)){
869
+					var tv = builder.get_object("tvLog") as Gtk.TextView;
870
+					var b = tv.get_buffer();
871
+					Gtk.TextIter end_iter, start_iter;
872
+					b.get_end_iter(out end_iter);
873
+					b.get_start_iter(out start_iter);
874
+					if (content != b.get_text(start_iter,end_iter,false)) {
875
+						b.set_text(content,-1);
876
+						b.get_end_iter(out end_iter);
877
+						tv.scroll_to_iter(end_iter, 0.0, true, 0.0, 0.0);
878
+					}
879
+				} else {
880
+					stderr.printf("Unable to read %s\n",SMD_LOGS_DIR+file);
881
+				}
882
+			} catch (GLib.FileError e) { 
883
+					stderr.printf("Unable to read %s: %s\n",
884
+						SMD_LOGS_DIR+file, e.message);
885
+			}
886
+		}
887
+	}
888
+
892 889
 	// ====================== public methods ==============================
893 890
 
894 891
 	// starts the thread and the timeout handler
895
-	public void run() throws Exit { 
892
+	public void start() throws Exit { 
896 893
 
897 894
 		// the timout function that will eventually notify the user
898 895
 		GLib.Timeout.add(1000, eat_event);
@@ -915,9 +912,8 @@ class smdApplet {
915 912
 		// since if we passed --configure the icon has not
916 913
 		// to be shown
917 914
 		if ( config_wait_mode ) {
918
-			// this is an hack to avoid cluttering the bar
919
-			si.set_visible(false);
920 915
 			while ( Gtk.events_pending() ) Gtk.main_iteration();
916
+			si.set_visible(false);
921 917
 			// we wait a bit, hopefully the gnome bar will be drawn in the
922 918
 			// meanwhile
923 919
 			Posix.sleep(5);
@@ -928,30 +924,19 @@ class smdApplet {
928 924
 			while ( Gtk.events_pending() ) Gtk.main_iteration();
929 925
 			// we do the notification
930 926
 			notification = new Notify.Notification(
931
-				"Syncmaildir","Syncmaildir is not configured properly, "+
932
-				"click on the icon to configure it.","dialog-warning");
927
+				"Syncmaildir","Syncmaildir is not configured properly.",
928
+				"dialog-error");
933 929
 			notification.set_hint("transient",new Variant.boolean(true));
930
+			notification.add_action("configure","Configure now",((n,a) =>
931
+				{ si.activate(); }));
934 932
 			try { notification.show(); }
935 933
 			catch (GLib.Error e) { stderr.printf("%s\n",e.message); }
936
-		} else {
937
-			si.set_visible(!settings.get_boolean(key_icon));
938 934
 		}
939 935
 
940
-		Gtk.main(); 
936
+		base.run(); 
941 937
 		if (thread != null) thread.join();
942 938
 	}
943 939
 
944
-	// just displays the config win
945
-	public void configure() {
946
-		var close = builder.get_object("bClosePrefs") as Gtk.Button;
947
-		close.clicked.connect(my_gtk_main_quit_button);
948
-		win.delete_event.connect(my_gtk_main_quit_event);
949
-		win.show();	
950
-		Gtk.main(); 
951
-		close.clicked.disconnect(my_gtk_main_quit_button);
952
-		win.delete_event.disconnect(my_gtk_main_quit_event);
953
-	}
954
-
955 940
 } // class end
956 941
 
957 942
 // =================== main =====================================
@@ -999,14 +984,7 @@ static int main(string[] args){
999 984
 	Gtk.init (ref args);
1000 985
 	Notify.init("smd-applet");
1001 986
 
1002
-	bool config_only=false;
1003 987
 	GLib.OptionEntry[] oe = {
1004
-      GLib.OptionEntry () { 
1005
-		long_name = "configure", short_name = 'c', 
1006
-		flags = 0, arg = GLib.OptionArg.NONE,
1007
-		arg_data = &config_only,
1008
-		description = "show config window, don't really run the applet",
1009
-		arg_description = null },
1010 988
       GLib.OptionEntry () { 
1011 989
 		long_name = "verbose", short_name = 'v',
1012 990
 		flags = 0, arg = GLib.OptionArg.NONE,
@@ -1029,12 +1007,8 @@ static int main(string[] args){
1029 1007
 
1030 1008
 	// go!
1031 1009
 	try { 
1032
-		var smd_applet = new smdApplet(config_only);
1033
-    	if ( config_only ) {
1034
-			smd_applet.configure();
1035
-		} else {
1036
-			smd_applet.run();
1037
-		}
1010
+		var smd_applet = new smdApplet();
1011
+		smd_applet.start();
1038 1012
 	} catch (Exit e) { 
1039 1013
 		stderr.printf("abort: %s\n",e.message); 
1040 1014
 		return 1;

+ 0
- 10
xdg/applications/smd-applet-configure.desktop View File

@@ -1,10 +0,0 @@
1
-[Desktop Entry]
2
-Name=Sync Mail Dir
3
-Name[it]=Sincronizzazione Maildir
4
-Comment=Configure Sync Mail Dir
5
-Comment[it]=Configura Sync Mail Dir
6
-Icon=mail-send-receive
7
-Exec=smd-applet --configure
8
-Terminal=false
9
-Type=Application
10
-Categories=Settings;GTK;GNOME;Email

Loading…
Cancel
Save