Merge lp:~elementary-pantheon/switchboard/switchboard-gmodule into lp:~elementary-pantheon/switchboard/switchboard

Proposed by Corentin Noël
Status: Merged
Approved by: Rico Tzschichholz
Approved revision: 446
Merged at revision: 414
Proposed branch: lp:~elementary-pantheon/switchboard/switchboard-gmodule
Merge into: lp:~elementary-pantheon/switchboard/switchboard
Diff against target: 2695 lines (+1189/-1106)
22 files modified
CMakeLists.txt (+81/-43)
cmake/FindGirCompiler.cmake (+56/-0)
cmake/Makefile (+0/-286)
cmake/Translations.cmake (+2/-1)
cmake/ValaPrecompile.cmake (+73/-11)
config.h.cmake (+0/-11)
lib/CMakeLists.txt (+74/-0)
lib/Plug.vala (+113/-0)
lib/PlugsManager.vala (+106/-0)
lib/config.vala.cmake (+9/-0)
lib/switchboard-2.0.deps (+6/-0)
lib/switchboard.pc.cmake (+12/-0)
po/CMakeLists.txt (+1/-1)
po/switchboard.pot (+34/-74)
sample/CMakeLists.txt (+29/-0)
sample/SamplePlug.vala (+67/-0)
src/CMakeLists.txt (+25/-0)
src/CategoryView.vala (+282/-140)
src/EmbeddedAlert.vala (+0/-1)
src/Resources.vala (+0/-15)
src/Switchboard.vala (+219/-514)
vapi/config.vapi (+0/-9)
To merge this branch: bzr merge lp:~elementary-pantheon/switchboard/switchboard-gmodule
Reviewer Review Type Date Requested Status
Rico Tzschichholz Approve
Cody Garver (community) Needs Fixing
Review via email: mp+195417@code.launchpad.net

Commit message

Introduce new plugin API using gmodule and GUI based on gtk+ 3.10

Description of the change

Switched to gmodule:
 * New Plug API
 * Now using the Gtk.Stack view switcher with animation
 * Now using the Gtk.HeaderBar
 * Multiarch compatibility

To post a comment you must log in.
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

<ricotz> tintou, regarding the libpeas branch don't use g-ir-scanner on the generated c-code
<ricotz> valac should create the gir and this one gets compiled with g-ir-compiler
<ricotz> otherwise the GI binding is useless and broken

<ricotz> tintou, since this is a new switchboard library you can start with 0 rather than 2
<tintou> ricotz: yes, but I think it's maybe better to follow switchboard version scheme
<ricotz> tintou, no, if you want a version then call it libswitchboard-2.0.so.0
<ricotz> which would be an API version

Revision history for this message
Rico Tzschichholz (ricotz) :
review: Needs Fixing
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

Good, it compiles now.

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

r416 is a no-go and should not be done that way.

review: Needs Fixing
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

The API could need some more thinking.

Public fields are not that great. E.g. Plug.vala contains a lot of fields which would better fit as "construct-only properties" or at least write-protected.

Of course this public API should have a proper valadoc-style documentation, not just some "// ..." comments.

review: Needs Fixing
Revision history for this message
Cody Garver (codygarver) wrote :

set (PLUGS_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/switchboard)

to

set (PLUGS_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/${CMAKE_PROJECT_NAME})

review: Needs Fixing
Revision history for this message
Corentin Noël (tintou) wrote :

Okay:
 * Added multiarch support
 * changed the API to a more solid one
 * Added valadoc-style documentation
 * changed switchboard to ${CMAKE_PROJECT_NAME}

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

private static SwitchboardApp _instance;
public static SwitchboardApp instance {
   get {
Dont use a property here!

"public Switchboard.PlugsManager plugs_manager;" should be private

I didnt want to you to get the impression that you need to refactor the whole source. This was mostly targeted to the lines you touched and the especially the plug api. If you touch every line, you won't make the reviewer happier So please don't re-intend without good reason and keep using "namespace Switchboard { ...". This is getting a bit out of hand: 2520 lines (+1145/-1147) 18 files modified and changing indentation in this amount should be done in a separate merge which states clearly that there are "no changes".

review: Needs Fixing
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

So please be consistent and keep all changed "namespace Switchboard { ... }" and do the same for new classes, etc.

review: Needs Fixing
Revision history for this message
Corentin Noël (tintou) wrote :

I don't want to use "namespace Switchboard { … }" anymore, so It won't be in newly written code, and it will be removed from old code after this will be merged.
It's not present in the CategoryView class anymore because this one was almost entirely rewritten.

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

I already mentioned my concerns about the Peas usage.
Look into using Peas.ExtensionBase and Peas.Activatable.

I would expect something like the following and its consequences, but I am not that familiar with peas yet.

    public abstract class Switchboard.Plug : Peas.ExtensionBase, Peas.Activatable {
    }

    exts = new Peas.ExtensionSet (engine, typeof (Switchboard.Plug), null);

Revision history for this message
Danielle Foré (danrabbit) wrote :

Not sure why, but with the latest revision switchboard's background is transparent

446. By Corentin Noël

Fixed code style and Changed ITEM_WIDTH to constant

Revision history for this message
Rico Tzschichholz (ricotz) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-12-03 14:30:40 +0000
3+++ CMakeLists.txt 2014-01-02 20:30:11 +0000
4@@ -5,21 +5,36 @@
5
6 # Base bits
7
8-#
9-
10-set (DATADIR "${CMAKE_INSTALL_PREFIX}/share")
11-set (PKGDATADIR "${DATADIR}/switchboard")
12-set (GETTEXT_PACKAGE "switchboard")
13+include (GNUInstallDirs)
14+set (DATADIR ${CMAKE_INSTALL_FULL_DATAROOTDIR})
15+set (PKGDATADIR "${DATADIR}/${CMAKE_PROJECT_NAME}")
16+set (GETTEXT_PACKAGE "${CMAKE_PROJECT_NAME}")
17 set (RELEASE_NAME "Preferences with piazzaz.")
18-set (VERSION "1.0.1")
19+set (PLUGS_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/${CMAKE_PROJECT_NAME})
20+set (VERSION "2.0.0")
21 set (VERSION_INFO "Stable Release")
22+
23+add_definitions ("-DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\"")
24+
25+# Comment this out to enable C compiler warnings
26+add_definitions (-w)
27+
28+option (BUILD_SHARED_LIBS "Switch between shared and static libraries" ON)
29+option (BUILD_SAMPLE "Build an example that shows how it works" OFF)
30+
31+if (BUILD_SHARED_LIBS)
32+ message ("-- Shared libraries enabled")
33+else ()
34+ message ("-- Shared libraries disabled")
35+endif ()
36+
37 #
38
39 # Niceties
40
41 #
42
43-set (ARCHIVE_NAME switchboard-${VERSION})
44+set (ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${VERSION})
45 add_custom_target (dist
46 COMMAND bzr export --root=${ARCHIVE_NAME} ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2
47 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
48@@ -38,21 +53,14 @@
49 add_dependencies(distcheck dist)
50 add_custom_target (uninstall "${CMAKE_COMMAND}" -P
51 "${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake")
52-#
53-
54-# config.h
55-
56-#
57-
58-configure_file (${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
59-add_definitions(-include config.h)
60+
61 #
62
63 # Data
64
65 #
66
67-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/switchboard.desktop DESTINATION /usr/share/applications)
68+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/${CMAKE_PROJECT_NAME}.desktop DESTINATION /usr/share/applications)
69 add_subdirectory(po)
70 #
71
72@@ -60,31 +68,61 @@
73
74 #
75
76+set (LIB_PACKAGES
77+ glib-2.0
78+ gio-2.0
79+ gee-1.0
80+ gmodule-2.0
81+ gtk+-3.0
82+ gio-unix-2.0
83+)
84+
85+set (LIB_PKG
86+ glib-2.0>=2.32
87+ gio-2.0
88+ gee-1.0
89+ gmodule-2.0
90+ gtk+-3.0>=3.10
91+ gio-unix-2.0
92+)
93 find_package(PkgConfig)
94-pkg_check_modules(DEPS REQUIRED granite gio-2.0 gee-1.0 gtk+-3.0>=3.6 unity)
95-add_definitions(${DEPS_CFLAGS})
96-link_directories(${DEPS_LIBRARY_DIRS})
97-find_package(Vala REQUIRED)
98-include(ValaVersion)
99-ensure_vala_version("0.18.0" MINIMUM)
100-include(ValaPrecompile)
101-vala_precompile(VALA_C
102- src/Switchboard.vala
103- src/CategoryView.vala
104- src/Resources.vala
105- src/DesktopLauncher.vala
106- src/EmbeddedAlert.vala
107- src/NavigationButton.vala
108-PACKAGES
109- granite
110- gee-1.0
111- gio-2.0
112- gtk+-3.0
113- unity
114-CUSTOM_VAPIS
115- vapi/config.vapi
116- )
117-add_definitions(${CFLAGS} -Wall -Winit-self -Wwrite-strings -Wunreachable-code -Wstrict-prototypes )
118-add_executable(switchboard ${VALA_C})
119-target_link_libraries(switchboard ${DEPS_LIBRARIES})
120-install(TARGETS switchboard RUNTIME DESTINATION bin)
121+
122+pkg_check_modules (LIB REQUIRED ${LIB_PKG})
123+
124+set (GLOBAL_VALAC_OPTIONS
125+ --vapidir=${CMAKE_BINARY_DIR}/lib
126+ --target-glib=2.32
127+ --thread
128+)
129+
130+find_package (Vala REQUIRED)
131+include (ValaVersion)
132+ensure_vala_version ("0.21.0" MINIMUM)
133+include (ValaPrecompile)
134+
135+add_subdirectory (lib)
136+
137+set (DEPS_PACKAGES
138+ ${LIB_NAME}
139+ ${LIB_PACKAGES} # this is needed until we provide a ${CMAKE_PROJECT_NAME}.deps file
140+ granite
141+ unity
142+)
143+
144+set (DEPS_PKG
145+ granite
146+ unity
147+)
148+
149+pkg_check_modules (DEPS REQUIRED ${DEPS_PKG} ${LIB_PKG})
150+set (DEPS_LIBRARIES ${DEPS_LIBRARIES} -lm)
151+
152+# 'src' and 'plugins' depend on the core library
153+include_directories (${CMAKE_BINARY_DIR}/lib)
154+set (DEPS_LIBRARIES ${DEPS_LIBRARIES} ${LIB_NAME})
155+add_subdirectory (src)
156+
157+
158+if (BUILD_SAMPLE)
159+ add_subdirectory (sample)
160+endif ()
161
162=== added file 'cmake/FindGirCompiler.cmake'
163--- cmake/FindGirCompiler.cmake 1970-01-01 00:00:00 +0000
164+++ cmake/FindGirCompiler.cmake 2014-01-02 20:30:11 +0000
165@@ -0,0 +1,56 @@
166+##
167+# Copyright 2009-2010 Jakob Westhoff. All rights reserved.
168+#
169+# Redistribution and use in source and binary forms, with or without
170+# modification, are permitted provided that the following conditions are met:
171+#
172+# 1. Redistributions of source code must retain the above copyright notice,
173+# this list of conditions and the following disclaimer.
174+#
175+# 2. Redistributions in binary form must reproduce the above copyright notice,
176+# this list of conditions and the following disclaimer in the documentation
177+# and/or other materials provided with the distribution.
178+#
179+# THIS SOFTWARE IS PROVIDED BY JAKOB WESTHOFF ``AS IS'' AND ANY EXPRESS OR
180+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
181+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
182+# EVENT SHALL JAKOB WESTHOFF OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
183+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
184+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
185+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
186+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
187+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
188+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
189+#
190+# The views and conclusions contained in the software and documentation are those
191+# of the authors and should not be interpreted as representing official policies,
192+# either expressed or implied, of Jakob Westhoff
193+##
194+
195+##
196+# Find module for the Gir compiler (g-ir-compiler)
197+#
198+# This module determines wheter a Gir compiler is installed on the current
199+# system and where its executable is.
200+#
201+# Call the module using "find_package(GirCompiler) from within your CMakeLists.txt.
202+#
203+# The following variables will be set after an invocation:
204+#
205+# G_IR_COMPILER_FOUND Whether the g-ir-compiler compiler has been found or not
206+# G_IR_COMPILER_EXECUTABLE Full path to the g-ir-compiler executable if it has been found
207+##
208+
209+
210+# Search for the g-ir-compiler executable in the usual system paths.
211+find_program (G_IR_COMPILER_EXECUTABLE
212+ NAMES g-ir-compiler)
213+
214+# Handle the QUIETLY and REQUIRED arguments, which may be given to the find call.
215+# Furthermore set G_IR_COMPILER_FOUND to TRUE if the g-ir-compiler has been found (aka.
216+# G_IR_COMPILER_EXECUTABLE is set)
217+
218+include (FindPackageHandleStandardArgs)
219+find_package_handle_standard_args (GirCompiler DEFAULT_MSG G_IR_COMPILER_EXECUTABLE)
220+
221+mark_as_advanced (G_IR_COMPILER_EXECUTABLE)
222
223=== removed file 'cmake/Makefile'
224--- cmake/Makefile 2012-01-13 17:02:58 +0000
225+++ cmake/Makefile 1970-01-01 00:00:00 +0000
226@@ -1,286 +0,0 @@
227-# CMAKE generated file: DO NOT EDIT!
228-# Generated by "Unix Makefiles" Generator, CMake Version 2.8
229-
230-# Default target executed when no arguments are given to make.
231-default_target: all
232-.PHONY : default_target
233-
234-#=============================================================================
235-# Special targets provided by cmake.
236-
237-# Disable implicit rules so canoncical targets will work.
238-.SUFFIXES:
239-
240-# Remove some rules from gmake that .SUFFIXES does not remove.
241-SUFFIXES =
242-
243-.SUFFIXES: .hpux_make_needs_suffix_list
244-
245-# Suppress display of executed commands.
246-$(VERBOSE).SILENT:
247-
248-# A target that is always out of date.
249-cmake_force:
250-.PHONY : cmake_force
251-
252-#=============================================================================
253-# Set environment variables for the build.
254-
255-# The shell in which to execute make rules.
256-SHELL = /bin/sh
257-
258-# The CMake executable.
259-CMAKE_COMMAND = /usr/bin/cmake
260-
261-# The command to remove a file.
262-RM = /usr/bin/cmake -E remove -f
263-
264-# The top-level source directory on which CMake was run.
265-CMAKE_SOURCE_DIR = /home/mefrio/Scrivania/cmake
266-
267-# The top-level build directory on which CMake was run.
268-CMAKE_BINARY_DIR = /home/mefrio/Scrivania/cmake/cmake
269-
270-#=============================================================================
271-# Targets provided globally by CMake.
272-
273-# Special rule for the target edit_cache
274-edit_cache:
275- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..."
276- /usr/bin/cmake -i .
277-.PHONY : edit_cache
278-
279-# Special rule for the target edit_cache
280-edit_cache/fast: edit_cache
281-.PHONY : edit_cache/fast
282-
283-# Special rule for the target install
284-install: preinstall
285- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
286- /usr/bin/cmake -P cmake_install.cmake
287-.PHONY : install
288-
289-# Special rule for the target install
290-install/fast: preinstall/fast
291- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
292- /usr/bin/cmake -P cmake_install.cmake
293-.PHONY : install/fast
294-
295-# Special rule for the target install/local
296-install/local: preinstall
297- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
298- /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
299-.PHONY : install/local
300-
301-# Special rule for the target install/local
302-install/local/fast: install/local
303-.PHONY : install/local/fast
304-
305-# Special rule for the target install/strip
306-install/strip: preinstall
307- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
308- /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
309-.PHONY : install/strip
310-
311-# Special rule for the target install/strip
312-install/strip/fast: install/strip
313-.PHONY : install/strip/fast
314-
315-# Special rule for the target list_install_components
316-list_install_components:
317- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
318-.PHONY : list_install_components
319-
320-# Special rule for the target list_install_components
321-list_install_components/fast: list_install_components
322-.PHONY : list_install_components/fast
323-
324-# Special rule for the target rebuild_cache
325-rebuild_cache:
326- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
327- /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
328-.PHONY : rebuild_cache
329-
330-# Special rule for the target rebuild_cache
331-rebuild_cache/fast: rebuild_cache
332-.PHONY : rebuild_cache/fast
333-
334-# The main all target
335-all: cmake_check_build_system
336- $(CMAKE_COMMAND) -E cmake_progress_start /home/mefrio/Scrivania/cmake/cmake/CMakeFiles /home/mefrio/Scrivania/cmake/cmake/CMakeFiles/progress.marks
337- $(MAKE) -f CMakeFiles/Makefile2 all
338- $(CMAKE_COMMAND) -E cmake_progress_start /home/mefrio/Scrivania/cmake/cmake/CMakeFiles 0
339-.PHONY : all
340-
341-# The main clean target
342-clean:
343- $(MAKE) -f CMakeFiles/Makefile2 clean
344-.PHONY : clean
345-
346-# The main clean target
347-clean/fast: clean
348-.PHONY : clean/fast
349-
350-# Prepare targets for installation.
351-preinstall: all
352- $(MAKE) -f CMakeFiles/Makefile2 preinstall
353-.PHONY : preinstall
354-
355-# Prepare targets for installation.
356-preinstall/fast:
357- $(MAKE) -f CMakeFiles/Makefile2 preinstall
358-.PHONY : preinstall/fast
359-
360-# clear depends
361-depend:
362- $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
363-.PHONY : depend
364-
365-#=============================================================================
366-# Target rules for targets named scratch
367-
368-# Build rule for target.
369-scratch: cmake_check_build_system
370- $(MAKE) -f CMakeFiles/Makefile2 scratch
371-.PHONY : scratch
372-
373-# fast build rule for target.
374-scratch/fast:
375- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/build
376-.PHONY : scratch/fast
377-
378-src/entry.o: src/entry.c.o
379-.PHONY : src/entry.o
380-
381-# target to build an object file
382-src/entry.c.o:
383- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/entry.c.o
384-.PHONY : src/entry.c.o
385-
386-src/entry.i: src/entry.c.i
387-.PHONY : src/entry.i
388-
389-# target to preprocess a source file
390-src/entry.c.i:
391- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/entry.c.i
392-.PHONY : src/entry.c.i
393-
394-src/entry.s: src/entry.c.s
395-.PHONY : src/entry.s
396-
397-# target to generate assembly for a file
398-src/entry.c.s:
399- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/entry.c.s
400-.PHONY : src/entry.c.s
401-
402-src/main_window.o: src/main_window.c.o
403-.PHONY : src/main_window.o
404-
405-# target to build an object file
406-src/main_window.c.o:
407- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/main_window.c.o
408-.PHONY : src/main_window.c.o
409-
410-src/main_window.i: src/main_window.c.i
411-.PHONY : src/main_window.i
412-
413-# target to preprocess a source file
414-src/main_window.c.i:
415- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/main_window.c.i
416-.PHONY : src/main_window.c.i
417-
418-src/main_window.s: src/main_window.c.s
419-.PHONY : src/main_window.s
420-
421-# target to generate assembly for a file
422-src/main_window.c.s:
423- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/main_window.c.s
424-.PHONY : src/main_window.c.s
425-
426-src/menu.o: src/menu.c.o
427-.PHONY : src/menu.o
428-
429-# target to build an object file
430-src/menu.c.o:
431- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/menu.c.o
432-.PHONY : src/menu.c.o
433-
434-src/menu.i: src/menu.c.i
435-.PHONY : src/menu.i
436-
437-# target to preprocess a source file
438-src/menu.c.i:
439- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/menu.c.i
440-.PHONY : src/menu.c.i
441-
442-src/menu.s: src/menu.c.s
443-.PHONY : src/menu.s
444-
445-# target to generate assembly for a file
446-src/menu.c.s:
447- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/menu.c.s
448-.PHONY : src/menu.c.s
449-
450-src/notebook.o: src/notebook.c.o
451-.PHONY : src/notebook.o
452-
453-# target to build an object file
454-src/notebook.c.o:
455- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/notebook.c.o
456-.PHONY : src/notebook.c.o
457-
458-src/notebook.i: src/notebook.c.i
459-.PHONY : src/notebook.i
460-
461-# target to preprocess a source file
462-src/notebook.c.i:
463- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/notebook.c.i
464-.PHONY : src/notebook.c.i
465-
466-src/notebook.s: src/notebook.c.s
467-.PHONY : src/notebook.s
468-
469-# target to generate assembly for a file
470-src/notebook.c.s:
471- $(MAKE) -f CMakeFiles/scratch.dir/build.make CMakeFiles/scratch.dir/src/notebook.c.s
472-.PHONY : src/notebook.c.s
473-
474-# Help Target
475-help:
476- @echo "The following are some of the valid targets for this Makefile:"
477- @echo "... all (the default if no target is provided)"
478- @echo "... clean"
479- @echo "... depend"
480- @echo "... edit_cache"
481- @echo "... install"
482- @echo "... install/local"
483- @echo "... install/strip"
484- @echo "... list_install_components"
485- @echo "... rebuild_cache"
486- @echo "... scratch"
487- @echo "... src/entry.o"
488- @echo "... src/entry.i"
489- @echo "... src/entry.s"
490- @echo "... src/main_window.o"
491- @echo "... src/main_window.i"
492- @echo "... src/main_window.s"
493- @echo "... src/menu.o"
494- @echo "... src/menu.i"
495- @echo "... src/menu.s"
496- @echo "... src/notebook.o"
497- @echo "... src/notebook.i"
498- @echo "... src/notebook.s"
499-.PHONY : help
500-
501-
502-
503-#=============================================================================
504-# Special targets to cleanup operation of make.
505-
506-# Special rule to run CMake to check the build system integrity.
507-# No rule that depends on this can have commands that come from listfiles
508-# because they might be regenerated.
509-cmake_check_build_system:
510- $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
511-.PHONY : cmake_check_build_system
512-
513
514=== modified file 'cmake/Translations.cmake' (properties changed: -x to +x)
515--- cmake/Translations.cmake 2012-06-05 05:30:28 +0000
516+++ cmake/Translations.cmake 2014-01-02 20:30:11 +0000
517@@ -36,6 +36,7 @@
518
519 add_custom_command (TARGET pot COMMAND
520 ${XGETTEXT_EXECUTABLE} -d ${NLS_PACKAGE} -o ${CMAKE_CURRENT_SOURCE_DIR}/${NLS_PACKAGE}.pot
521- ${VALA_SOURCE} ${C_SOURCE} --keyword="_" --keyword="N_" --from-code=UTF-8
522+ ${VALA_SOURCE} ${C_SOURCE} --add-comments="/" --keyword="_" --keyword="N_" --keyword="C_:1c,2"
523+ --keyword="NC_:1c,2" --keyword="ngettext:1,2" --keyword="N_" --keyword="Q_:1g" --from-code=UTF-8
524 )
525 endmacro()
526
527=== modified file 'cmake/ValaPrecompile.cmake'
528--- cmake/ValaPrecompile.cmake 2012-01-13 17:02:58 +0000
529+++ cmake/ValaPrecompile.cmake 2014-01-02 20:30:11 +0000
530@@ -1,5 +1,6 @@
531 ##
532 # Copyright 2009-2010 Jakob Westhoff. All rights reserved.
533+# Copyright 2012 elementary.
534 #
535 # Redistribution and use in source and binary forms, with or without
536 # modification, are permitted provided that the following conditions are met:
537@@ -74,10 +75,18 @@
538 # be a header file as well as an internal header file being generated called
539 # <provided_name>.h and <provided_name>_internal.h
540 #
541+# GENERATE_GIR
542+# Have the compiler generate a GObject-Introspection repository file with
543+# name: <provided_name>.gir. This can be later used to create a binary typelib
544+# using the GI compiler.
545+#
546+# GENERATE_SYMBOLS
547+# Output a <provided_name>.symbols file containing all the exported symbols.
548+#
549 # The following call is a simple example to the vala_precompile macro showing
550 # an example to every of the optional sections:
551 #
552-# vala_precompile(VALA_C
553+# vala_precompile(VALA_C mytargetname
554 # source1.vala
555 # source2.vala
556 # source3.vala
557@@ -95,14 +104,19 @@
558 # myvapi
559 # GENERATE_HEADER
560 # myheader
561+# GENERATE_GIR
562+# mygir
563+# GENERATE_SYMBOLS
564+# mysymbols
565 # )
566 #
567 # Most important is the variable VALA_C which will contain all the generated c
568 # file names after the call.
569 ##
570
571-macro(vala_precompile output)
572- parse_arguments(ARGS "PACKAGES;OPTIONS;DIRECTORY;GENERATE_HEADER;GENERATE_VAPI;CUSTOM_VAPIS" "" ${ARGN})
573+macro(vala_precompile output target_name)
574+ parse_arguments(ARGS "TARGET;PACKAGES;OPTIONS;DIRECTORY;GENERATE_GIR;GENERATE_SYMBOLS;GENERATE_HEADER;GENERATE_VAPI;CUSTOM_VAPIS" "" ${ARGN})
575+
576 if(ARGS_DIRECTORY)
577 set(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_DIRECTORY})
578 else(ARGS_DIRECTORY)
579@@ -115,14 +129,17 @@
580 endforeach(pkg ${ARGS_PACKAGES})
581 set(in_files "")
582 set(out_files "")
583+ set(out_files_display "")
584 set(${output} "")
585+
586 foreach(src ${ARGS_DEFAULT_ARGS})
587 string(REGEX MATCH "^/" IS_MATCHED ${src})
588 if(${IS_MATCHED} MATCHES "/")
589- list(APPEND in_files "${src}")
590+ set(src_file_path ${src})
591 else()
592- list(APPEND in_files "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
593+ set(src_file_path ${CMAKE_CURRENT_SOURCE_DIR}/${src})
594 endif()
595+ list(APPEND in_files ${src_file_path})
596 string(REPLACE ".vala" ".c" src ${src})
597 string(REPLACE ".gs" ".c" src ${src})
598 if(${IS_MATCHED} MATCHES "/")
599@@ -134,6 +151,7 @@
600 list(APPEND out_files "${DIRECTORY}/${src}")
601 endif()
602 list(APPEND ${output} ${out_file})
603+ list(APPEND out_files_display "${src}")
604 endforeach(src ${ARGS_DEFAULT_ARGS})
605
606 set(custom_vapi_arguments "")
607@@ -150,7 +168,8 @@
608 set(vapi_arguments "")
609 if(ARGS_GENERATE_VAPI)
610 list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_VAPI}.vapi")
611- set(vapi_arguments "--internal-vapi=${ARGS_GENERATE_VAPI}.vapi")
612+ list(APPEND out_files_display "${ARGS_GENERATE_VAPI}.vapi")
613+ set(vapi_arguments "--library=${ARGS_GENERATE_VAPI}" "--vapi=${ARGS_GENERATE_VAPI}.vapi")
614
615 # Header and internal header is needed to generate internal vapi
616 if (NOT ARGS_GENERATE_HEADER)
617@@ -161,26 +180,69 @@
618 set(header_arguments "")
619 if(ARGS_GENERATE_HEADER)
620 list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_HEADER}.h")
621- list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_HEADER}_internal.h")
622- list(APPEND header_arguments "--header=${DIRECTORY}/${ARGS_GENERATE_HEADER}.h")
623- list(APPEND header_arguments "--internal-header=${DIRECTORY}/${ARGS_GENERATE_HEADER}_internal.h")
624+ list(APPEND out_files_display "${ARGS_GENERATE_HEADER}.h")
625+ list(APPEND header_arguments "--header=${ARGS_GENERATE_HEADER}.h")
626 endif(ARGS_GENERATE_HEADER)
627
628- add_custom_command(OUTPUT ${out_files}
629+ set(gir_arguments "")
630+ set(gircomp_command "")
631+ if(ARGS_GENERATE_GIR)
632+ list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_GIR}.gir")
633+ list(APPEND out_files_display "${ARGS_GENERATE_GIR}.gir")
634+ set(gir_arguments "--gir=${ARGS_GENERATE_GIR}.gir")
635+
636+ include (FindGirCompiler)
637+ find_package(GirCompiler REQUIRED)
638+
639+ set(gircomp_command
640+ COMMAND
641+ ${G_IR_COMPILER_EXECUTABLE}
642+ ARGS
643+ "${DIRECTORY}/${ARGS_GENERATE_GIR}.gir"
644+ -o "${DIRECTORY}/${ARGS_GENERATE_GIR}.typelib")
645+ endif(ARGS_GENERATE_GIR)
646+
647+ set(symbols_arguments "")
648+ if(ARGS_GENERATE_SYMBOLS)
649+ list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_SYMBOLS}.symbols")
650+ list(APPEND out_files_display "${ARGS_GENERATE_SYMBOLS}.symbols")
651+ set(symbols_arguments "--symbols=${ARGS_GENERATE_SYMBOLS}.symbols")
652+ endif(ARGS_GENERATE_SYMBOLS)
653+
654+ # Workaround for a bug that would make valac run twice. This file is written
655+ # after the vala compiler generates C source code.
656+ set(OUTPUT_STAMP ${CMAKE_CURRENT_BINARY_DIR}/${target_name}_valac.stamp)
657+
658+ add_custom_command(
659+ OUTPUT
660+ ${OUTPUT_STAMP}
661 COMMAND
662 ${VALA_EXECUTABLE}
663 ARGS
664 "-C"
665 ${header_arguments}
666- ${vapi_arguments}
667+ ${vapi_arguments}
668+ ${gir_arguments}
669+ ${symbols_arguments}
670 "-b" ${CMAKE_CURRENT_SOURCE_DIR}
671 "-d" ${DIRECTORY}
672 ${vala_pkg_opts}
673 ${ARGS_OPTIONS}
674 ${in_files}
675 ${custom_vapi_arguments}
676+ COMMAND
677+ touch
678+ ARGS
679+ ${OUTPUT_STAMP}
680 DEPENDS
681 ${in_files}
682 ${ARGS_CUSTOM_VAPIS}
683+ COMMENT
684+ "Generating ${out_files_display}"
685+ ${gircomp_command}
686 )
687+
688+ # This command will be run twice for some reason (pass a non-empty string to COMMENT
689+ # in order to see it). Since valac is not executed from here, this won't be a problem.
690+ add_custom_command(OUTPUT ${out_files} DEPENDS ${OUTPUT_STAMP} COMMENT "")
691 endmacro(vala_precompile)
692
693=== removed file 'config.h.cmake'
694--- config.h.cmake 2011-06-23 05:56:29 +0000
695+++ config.h.cmake 1970-01-01 00:00:00 +0000
696@@ -1,11 +0,0 @@
697-#ifndef CONFIG_H
698-#define CONFIG_H
699-
700-#cmakedefine DATADIR "@DATADIR@"
701-#cmakedefine PKGDATADIR "@PKGDATADIR@"
702-#cmakedefine GETTEXT_PACKAGE "@GETTEXT_PACKAGE@"
703-#cmakedefine RELEASE_NAME "@RELEASE_NAME@"
704-#cmakedefine VERSION "@VERSION@"
705-#cmakedefine VERSION_INFO "@VERSION_INFO@"
706-
707-#endif // CONFIG_H
708
709=== added directory 'lib'
710=== added file 'lib/CMakeLists.txt'
711--- lib/CMakeLists.txt 1970-01-01 00:00:00 +0000
712+++ lib/CMakeLists.txt 2014-01-02 20:30:11 +0000
713@@ -0,0 +1,74 @@
714+######################
715+# Set Variables
716+######################
717+
718+set (CONFIG_FILE ${CMAKE_CURRENT_BINARY_DIR}/config.vala)
719+set (PREFIX ${CMAKE_INSTALL_PREFIX})
720+set (DOLLAR "$") # You hear that? It's kittens being killed by the gods of cmake
721+set (LIB_VERSION 2.0)
722+set (LIB_VERSION ${LIB_VERSION} PARENT_SCOPE)
723+set (LIB_SOVERSION 0)
724+set (LIB_SOVERSION ${LIB_SOVERSION} PARENT_SCOPE)
725+set (LIB_NAME ${CMAKE_PROJECT_NAME}-${LIB_VERSION})
726+set (LIB_NAME ${LIB_NAME} PARENT_SCOPE)
727+
728+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.vala.cmake ${CONFIG_FILE})
729+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}.pc)
730+
731+set (LIB_SOURCE
732+ ${CONFIG_FILE}
733+ Plug.vala
734+ PlugsManager.vala
735+)
736+
737+if (BUILD_SHARED_LIBS)
738+ set (LINK_MODE SHARED)
739+else ()
740+ set (LINK_MODE STATIC)
741+endif ()
742+
743+######################
744+# Generate .c, .vapi, .gir and .h
745+######################
746+
747+vala_precompile (LIB_VALA_C ${LIB_NAME}
748+ ${LIB_SOURCE}
749+ PACKAGES
750+ ${LIB_PACKAGES}
751+ OPTIONS
752+ ${GLOBAL_VALAC_OPTIONS}
753+ GENERATE_VAPI
754+ ${LIB_NAME}
755+ GENERATE_HEADER
756+ ${CMAKE_PROJECT_NAME}
757+)
758+
759+######################
760+# Include definitions
761+######################
762+
763+add_definitions (${LIB_CFLAGS})
764+link_directories (${LIB_LIBRARY_DIRS})
765+
766+add_library (${LIB_NAME} ${LINK_MODE} ${LIB_VALA_C})
767+
768+set_target_properties (${LIB_NAME} PROPERTIES
769+ OUTPUT_NAME ${LIB_NAME}
770+ VERSION ${LIB_VERSION}
771+ SOVERSION ${LIB_SOVERSION}
772+)
773+
774+target_link_libraries (${LIB_NAME} ${LIB_LIBRARIES})
775+
776+######################
777+# Installation
778+######################
779+
780+if (BUILD_SHARED_LIBS)
781+ install (TARGETS ${LIB_NAME} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
782+ # Install lib stuffs
783+ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}.pc DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig/)
784+ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}.vapi DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/vala/vapi/)
785+ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.deps DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/vala/vapi/)
786+ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.h DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/${LIB_NAME}/)
787+endif ()
788
789=== added file 'lib/Plug.vala'
790--- lib/Plug.vala 1970-01-01 00:00:00 +0000
791+++ lib/Plug.vala 2014-01-02 20:30:11 +0000
792@@ -0,0 +1,113 @@
793+// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
794+/*-
795+ * Copyright (c) 2012-2013 Switchboard Developers (http://launchpad.net/switchboard)
796+ *
797+ * This library is free software; you can redistribute it and/or
798+ * modify it under the terms of the GNU Library General Public
799+ * License as published by the Free Software Foundation; either
800+ * version 2 of the License, or (at your option) any later version.
801+ *
802+ * This library is distributed in the hope that it will be useful,
803+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
804+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
805+ * Library General Public License for more details.
806+ *
807+ * You should have received a copy of the GNU Library General Public
808+ * License along with this library; if not, write to the
809+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
810+ * Boston, MA 02111-1307, USA.
811+ *
812+ * Authored by: Corentin Noël <tintou@mailoo.org>
813+ */
814+
815+public abstract class Switchboard.Plug : GLib.Object {
816+
817+ public enum Category {
818+ PERSONAL = 0,
819+ HARDWARE = 1,
820+ NETWORK = 2,
821+ SYSTEM = 3,
822+ OTHER = 4
823+ }
824+
825+ /**
826+ * The common used separator.
827+ */
828+ public const string SEP = "<sep>";
829+
830+ /**
831+ * The category under which the plug will be stored.
832+ *
833+ * Possible {@link Category} values are PERSONAL, HARDWARE, NETWORK or SYSTEM.
834+ */
835+ public Category category { get; construct; }
836+
837+ /**
838+ * The unique name representing the plug.
839+ *
840+ * It is also used to recognise it with the open-plug command.
841+ * for example "system-pantheon-info" for the official Info plug of the pantheon desktop.
842+ */
843+ public string code_name { get; construct; }
844+
845+ /**
846+ * The localised name of the plug.
847+ */
848+ public string display_name { get; construct; }
849+
850+ /**
851+ * A short description of the plug.
852+ */
853+ public string description { get; construct; }
854+
855+ /**
856+ * The icon representing the plug.
857+ */
858+ public string icon { get; construct; }
859+
860+ /**
861+ * Inform if the plug should be shown or not
862+ */
863+ public bool can_show { get; set; default=true;}
864+
865+ /**
866+ * Inform the application that the plug can now be listed in the available plugs
867+ */
868+ public signal void visibility_changed ();
869+
870+ /**
871+ * Returns the widget that contain the whole interface.
872+ *
873+ * @return a {@link Gtk.Widget} containing the interface.
874+ */
875+ public abstract Gtk.Widget get_widget ();
876+
877+ /**
878+ * Called when the plug appears to the user.
879+ */
880+ public abstract void shown ();
881+
882+ /**
883+ * Called when the plug disappear to the user.
884+ *
885+ * This is not called when the plug got destroyed or the window is closed, use ~Plug () instead.
886+ */
887+ public abstract void hidden ();
888+
889+ /**
890+ * This function should return the widget that contain the whole interface.
891+ *
892+ * When the user click on an action, the second parameter is send to the {@link search_callback} method
893+ *
894+ * @param search a {@link string} that represent the search.
895+ * @return a {@link Gee.TreeMap} containing two strings like {"Keyboard → Behavior → Duration", "keyboard<sep>behavior"}.
896+ */
897+ public abstract async Gee.TreeMap<string, string> search (string search);
898+
899+ /**
900+ * This function is used when the user click on a search result, it should show the selected setting (right tab…).
901+ *
902+ * @param location a {@link string} that represents the setting to show.
903+ */
904+ public abstract void search_callback (string location);
905+}
906
907=== added file 'lib/PlugsManager.vala'
908--- lib/PlugsManager.vala 1970-01-01 00:00:00 +0000
909+++ lib/PlugsManager.vala 2014-01-02 20:30:11 +0000
910@@ -0,0 +1,106 @@
911+// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
912+/*-
913+ * Copyright (c) 2012-2013 Switchboard Developers (http://launchpad.net/switchboard)
914+ *
915+ * This library is free software; you can redistribute it and/or
916+ * modify it under the terms of the GNU Library General Public
917+ * License as published by the Free Software Foundation; either
918+ * version 2 of the License, or (at your option) any later version.
919+ *
920+ * This library is distributed in the hope that it will be useful,
921+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
922+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
923+ * Library General Public License for more details.
924+ *
925+ * You should have received a copy of the GNU Library General Public
926+ * License along with this library; if not, write to the
927+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
928+ * Boston, MA 02111-1307, USA.
929+ *
930+ * Authored by: Corentin Noël <tintou@mailoo.org>
931+ */
932+
933+public class Switchboard.PlugsManager : GLib.Object {
934+
935+ private static Switchboard.PlugsManager? plugs_manager = null;
936+
937+ public static PlugsManager get_default () {
938+ if (plugs_manager == null)
939+ plugs_manager = new PlugsManager ();
940+ return plugs_manager;
941+ }
942+
943+ [CCode (has_target = false)]
944+ private delegate Switchboard.Plug RegisterPluginFunction (Module module);
945+
946+ private Gee.LinkedList<Switchboard.Plug> plugs;
947+
948+ public signal void plug_added (Switchboard.Plug plug);
949+
950+ private PlugsManager () {
951+ plugs = new Gee.LinkedList<Switchboard.Plug> ();
952+ var base_folder = File.new_for_path (Build.PLUGS_DIR);
953+ find_plugins (base_folder);
954+ }
955+
956+ private void load (string path) {
957+ if (Module.supported () == false) {
958+ error ("Switchboard is not supported by this system!");
959+ }
960+
961+ Module module = Module.open (path, ModuleFlags.BIND_LAZY);
962+ if (module == null) {
963+ critical (Module.error ());
964+ return;
965+ }
966+
967+ void* function;
968+ module.symbol ("get_plug", out function);
969+ if (function == null) {
970+ critical ("get_plug () not found in %s", path);
971+ return;
972+ }
973+
974+ RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
975+ Switchboard.Plug plug = register_plugin (module);
976+ if (plug == null) {
977+ critical ("Unknown plugin type for %s !", path);
978+ return;
979+ }
980+ module.make_resident ();
981+ register_plug (plug);
982+ }
983+
984+ private void find_plugins (File base_folder) {
985+ FileInfo file_info = null;
986+ try {
987+ var enumerator = base_folder.enumerate_children (FileAttribute.STANDARD_NAME + "," + FileAttribute.STANDARD_TYPE + "," + FileAttribute.STANDARD_CONTENT_TYPE, 0);
988+ while ((file_info = enumerator.next_file ()) != null) {
989+ var file = base_folder.get_child (file_info.get_name ());
990+
991+ if (file_info.get_file_type () == FileType.REGULAR && GLib.ContentType.equals (file_info.get_content_type (), "application/x-sharedlib")) {
992+ load (file.get_path ());
993+ } else if (file_info.get_file_type () == FileType.DIRECTORY) {
994+ find_plugins (file);
995+ }
996+ }
997+ } catch (Error err) {
998+ warning("Unable to scan plugs folder: %s\n", err.message);
999+ }
1000+ }
1001+
1002+ private void register_plug (Switchboard.Plug plug) {
1003+ if (plugs.contains (plug))
1004+ return;
1005+ plugs.add (plug);
1006+ plug_added (plug);
1007+ }
1008+
1009+ public bool has_plugs () {
1010+ return !plugs.is_empty;
1011+ }
1012+
1013+ public Gee.Collection<Switchboard.Plug> get_plugs () {
1014+ return plugs.read_only_view;
1015+ }
1016+}
1017\ No newline at end of file
1018
1019=== added file 'lib/config.vala.cmake'
1020--- lib/config.vala.cmake 1970-01-01 00:00:00 +0000
1021+++ lib/config.vala.cmake 2014-01-02 20:30:11 +0000
1022@@ -0,0 +1,9 @@
1023+namespace Switchboard.Build {
1024+ public const string DATADIR = "@DATADIR@";
1025+ public const string PKGDATADIR = "@PKGDATADIR@";
1026+ public const string PLUGS_DIR = "@PLUGS_DIR@";
1027+ public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@";
1028+ public const string RELEASE_NAME = "@RELEASE_NAME@";
1029+ public const string VERSION = "@VERSION@";
1030+ public const string VERSION_INFO = "@VERSION_INFO@";
1031+}
1032
1033=== added file 'lib/switchboard-2.0.deps'
1034--- lib/switchboard-2.0.deps 1970-01-01 00:00:00 +0000
1035+++ lib/switchboard-2.0.deps 2014-01-02 20:30:11 +0000
1036@@ -0,0 +1,6 @@
1037+glib-2.0
1038+gio-2.0
1039+gee-1.0
1040+gmodule-2.0
1041+gtk+-3.0
1042+gio-unix-2.0
1043
1044=== added file 'lib/switchboard.pc.cmake'
1045--- lib/switchboard.pc.cmake 1970-01-01 00:00:00 +0000
1046+++ lib/switchboard.pc.cmake 2014-01-02 20:30:11 +0000
1047@@ -0,0 +1,12 @@
1048+prefix=@PREFIX@
1049+exec_prefix=@DOLLAR@{prefix}
1050+libdir=@DOLLAR@{prefix}/lib
1051+includedir=@DOLLAR@{prefix}/include/
1052+
1053+Name: Switchboard
1054+Description: Switchboard headers
1055+Version: 2.0
1056+Libs: -lswitchboard-2.0
1057+Cflags: -I@DOLLAR@{includedir}/switchboard-2.0
1058+Requires: glib-2.0 gio-2.0 gee-1.0 gmodule-2.0 gtk+-3.0 gio-unix-2.0
1059+
1060
1061=== modified file 'po/CMakeLists.txt'
1062--- po/CMakeLists.txt 2012-01-13 17:02:58 +0000
1063+++ po/CMakeLists.txt 2014-01-02 20:30:11 +0000
1064@@ -1,5 +1,5 @@
1065 include(Translations)
1066 add_translations_directory("switchboard")
1067 add_translations_catalog("switchboard"
1068- ../Switchboard/
1069+ ../src/
1070 )
1071
1072=== modified file 'po/switchboard.pot'
1073--- po/switchboard.pot 2012-08-02 04:47:30 +0000
1074+++ po/switchboard.pot 2014-01-02 20:30:11 +0000
1075@@ -8,7 +8,7 @@
1076 msgstr ""
1077 "Project-Id-Version: PACKAGE VERSION\n"
1078 "Report-Msgid-Bugs-To: \n"
1079-"POT-Creation-Date: 2012-08-01 23:47-0500\n"
1080+"POT-Creation-Date: 2013-12-14 17:45+0100\n"
1081 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1082 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1083 "Language-Team: LANGUAGE <LL@li.org>\n"
1084@@ -17,96 +17,56 @@
1085 "Content-Type: text/plain; charset=CHARSET\n"
1086 "Content-Transfer-Encoding: 8bit\n"
1087
1088-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:29
1089+#: /home/noelco/libpeas-isis/po/../src//DesktopLauncher.vala:6
1090+msgid "Change system and user settings"
1091+msgstr ""
1092+
1093+#: /home/noelco/libpeas-isis/po/../src//DesktopLauncher.vala:7
1094+msgid "Settings Center"
1095+msgstr ""
1096+
1097+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:174
1098+#, c-format
1099+msgid "Unable to load plug %s's icon: %s"
1100+msgstr ""
1101+
1102+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:211
1103+#: /home/noelco/libpeas-isis/po/../src//Switchboard.vala:132
1104+msgid "No settings found"
1105+msgstr ""
1106+
1107+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:211
1108+msgid "Try changing your search terms"
1109+msgstr ""
1110+
1111+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:302
1112 msgid "Personal"
1113 msgstr ""
1114
1115-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:29
1116+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:305
1117 msgid "Hardware"
1118 msgstr ""
1119
1120-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:29
1121+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:308
1122 msgid "Network and Wireless"
1123 msgstr ""
1124
1125-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:29
1126+#: /home/noelco/libpeas-isis/po/../src//CategoryView.vala:311
1127 msgid "System"
1128 msgstr ""
1129
1130-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:85
1131-#, c-format
1132-msgid ""
1133-"Keyfile \"%s\" contains an invalid category: \"%s\", and will not be added"
1134-msgstr ""
1135-
1136-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:94
1137-#, c-format
1138-msgid "Unable to load plug %s's icon: %s"
1139-msgstr ""
1140-
1141-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:137
1142-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:159
1143-msgid "No settings found"
1144-msgstr ""
1145-
1146-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-categoryview.vala:137
1147-msgid "Try changing your search terms"
1148-msgstr ""
1149-
1150-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-desktoplauncher.vala:6
1151-msgid "Change system and user settings"
1152-msgstr ""
1153-
1154-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-desktoplauncher.vala:7
1155-msgid "Settings Center"
1156-msgstr ""
1157-
1158-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:159
1159+#: /home/noelco/libpeas-isis/po/../src//Switchboard.vala:38
1160+msgid "All Settings"
1161+msgstr ""
1162+
1163+#: /home/noelco/libpeas-isis/po/../src//Switchboard.vala:132
1164 msgid "Install some and re-launch Switchboard"
1165 msgstr ""
1166
1167-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:213
1168-#, c-format
1169-msgid "Closing plug \"%s\" in Switchboard controller..."
1170-msgstr ""
1171-
1172-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:225
1173-#, c-format
1174-msgid "Failed to launch plug: title %s | executable %s"
1175-msgstr ""
1176-
1177-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:322
1178-msgid "title"
1179-msgstr ""
1180-
1181-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:369
1182-msgid "Unable to iterate over enumerated plug directory \"$path\"'s contents"
1183-msgstr ""
1184-
1185-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:462
1186+#: /home/noelco/libpeas-isis/po/../src//Switchboard.vala:215
1187 msgid "Search Settings"
1188 msgstr ""
1189
1190-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:492
1191+#: /home/noelco/libpeas-isis/po/../src//Switchboard.vala:315
1192 msgid "Open a plug"
1193 msgstr ""
1194-
1195-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:501
1196-msgid "Welcome to $APP_TITLE"
1197-msgstr ""
1198-
1199-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:502
1200-msgid "Version: $VERSION"
1201-msgstr ""
1202-
1203-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:503
1204-msgid "Report any issues/bugs you mind find to lp:switchboard"
1205-msgstr ""
1206-
1207-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-app.vala:526
1208-msgid "Switchboard already running. Exiting.."
1209-msgstr ""
1210-
1211-#: /home/codygarver/switchboard/po/../Switchboard//switchboard-resources.vala:3
1212-msgid "System Settings"
1213-msgstr ""
1214
1215=== added directory 'sample'
1216=== added file 'sample/CMakeLists.txt'
1217--- sample/CMakeLists.txt 1970-01-01 00:00:00 +0000
1218+++ sample/CMakeLists.txt 2014-01-02 20:30:11 +0000
1219@@ -0,0 +1,29 @@
1220+find_package (PkgConfig)
1221+
1222+# Add all your dependencies to the list below
1223+pkg_check_modules (DEPS REQUIRED gthread-2.0 gtk+-3.0 switchboard-2.0)
1224+
1225+add_definitions (${DEPS_CFLAGS})
1226+link_directories (${DEPS_LIBRARY_DIRS})
1227+set (SAMPLEPLUG "plug-sample")
1228+
1229+find_package (Vala REQUIRED)
1230+include (ValaVersion)
1231+ensure_vala_version ("0.12.0" MINIMUM)
1232+
1233+include (ValaPrecompile)
1234+# Add all your vala files and requires packages to the List below to include them in the build
1235+vala_precompile (VALA_C ${SAMPLEPLUG}
1236+ SamplePlug.vala
1237+PACKAGES
1238+ gtk+-3.0
1239+ switchboard-2.0
1240+OPTIONS
1241+ --thread
1242+)
1243+
1244+add_library (${SAMPLEPLUG} MODULE ${VALA_C})
1245+target_link_libraries(${SAMPLEPLUG} ${DEPS_LIBRARIES})
1246+
1247+# Installation
1248+install (TARGETS ${SAMPLEPLUG} DESTINATION "${PLUGS_DIR}/${PLUGNAME}")
1249\ No newline at end of file
1250
1251=== added file 'sample/SamplePlug.vala'
1252--- sample/SamplePlug.vala 1970-01-01 00:00:00 +0000
1253+++ sample/SamplePlug.vala 2014-01-02 20:30:11 +0000
1254@@ -0,0 +1,67 @@
1255+// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
1256+/*-
1257+ * Copyright (c) 2012-2013 Switchboard Developers (http://launchpad.net/switchboard)
1258+ *
1259+ * This library is free software; you can redistribute it and/or
1260+ * modify it under the terms of the GNU Library General Public
1261+ * License as published by the Free Software Foundation; either
1262+ * version 2 of the License, or (at your option) any later version.
1263+ *
1264+ * This library is distributed in the hope that it will be useful,
1265+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1266+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1267+ * Library General Public License for more details.
1268+ *
1269+ * You should have received a copy of the GNU Library General Public
1270+ * License along with this library; if not, write to the
1271+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1272+ * Boston, MA 02111-1307, USA.
1273+ *
1274+ * Authored by: Corentin Noël <tintou@mailoo.org>
1275+ */
1276+
1277+public class Sample.Plug : Switchboard.Plug {
1278+
1279+ private Gtk.Grid main_grid;
1280+
1281+ public Plug () {
1282+ Object (category: Category.SYSTEM,
1283+ code_name: "sample-plug",
1284+ display_name: _("Sample Plug"),
1285+ description:_("Does nothing, but it is cool !"),
1286+ icon: "system-run");
1287+ }
1288+
1289+ public override Gtk.Widget get_widget () {
1290+ if (main_grid == null) {
1291+ main_grid = new Gtk.Grid ();
1292+ var hello_label = new Gtk.Label ("Hello World!");
1293+ main_grid.attach (hello_label, 0, 0, 1, 1);
1294+ }
1295+ main_grid.show_all ();
1296+ return main_grid;
1297+ }
1298+
1299+ public override void shown () {
1300+
1301+ }
1302+
1303+ public override void hidden () {
1304+
1305+ }
1306+
1307+ public override void search_callback (string location) {
1308+
1309+ }
1310+
1311+ // 'search' returns results like ("Keyboard → Behavior → Duration", "keyboard<sep>behavior")
1312+ public override async Gee.TreeMap<string, string> search (string search) {
1313+ return new Gee.TreeMap<string, string> (null, null);
1314+ }
1315+}
1316+
1317+public Switchboard.Plug get_plug (Module module) {
1318+ debug ("Activating Sample plug");
1319+ var plug = new Sample.Plug ();
1320+ return plug;
1321+}
1322\ No newline at end of file
1323
1324=== added file 'src/CMakeLists.txt'
1325--- src/CMakeLists.txt 1970-01-01 00:00:00 +0000
1326+++ src/CMakeLists.txt 2014-01-02 20:30:11 +0000
1327@@ -0,0 +1,25 @@
1328+set(CLIENT_SOURCE
1329+ Switchboard.vala
1330+ CategoryView.vala
1331+ DesktopLauncher.vala
1332+ EmbeddedAlert.vala
1333+ NavigationButton.vala
1334+)
1335+
1336+vala_precompile (CLIENT_VALA_C ${CMAKE_PROJECT_NAME}
1337+ ${CLIENT_SOURCE}
1338+ PACKAGES
1339+ ${DEPS_PACKAGES}
1340+ OPTIONS
1341+ ${GLOBAL_VALAC_OPTIONS}
1342+)
1343+
1344+set (EXEC_NAME ../${CMAKE_PROJECT_NAME})
1345+
1346+add_definitions (${DEPS_CFLAGS})
1347+link_directories (${DEPS_LIBRARY_DIRS})
1348+add_executable (${EXEC_NAME} ${CLIENT_VALA_C})
1349+
1350+target_link_libraries (${EXEC_NAME} ${DEPS_LIBRARIES})
1351+
1352+install (TARGETS ${EXEC_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
1353
1354=== modified file 'src/CategoryView.vala'
1355--- src/CategoryView.vala 2013-09-29 19:41:03 +0000
1356+++ src/CategoryView.vala 2014-01-02 20:30:11 +0000
1357@@ -19,160 +19,290 @@
1358
1359 public class CategoryView : Gtk.Grid {
1360
1361- public Gee.HashMap<string, Gtk.Grid> category_labels = new Gee.HashMap<string, Gtk.Grid> ();
1362- public Gee.HashMap<string, Gtk.ListStore> category_store = new Gee.HashMap<string, Gtk.ListStore> ();
1363- public Gee.HashMap<string, Gtk.IconView> category_views = new Gee.HashMap<string, Gtk.IconView> ();
1364+ public enum Columns {
1365+ ICON,
1366+ TEXT,
1367+ DESCRIPTION,
1368+ VISIBLE,
1369+ PLUG,
1370+ N_COLUMNS
1371+ }
1372+
1373+ const int ITEM_WIDTH = 96;
1374+
1375+ public signal void plug_selected (Switchboard.Plug plug);
1376+
1377 Gtk.IconTheme theme = Gtk.IconTheme.get_default ();
1378-
1379- public signal void plug_selected (string title, string executable, bool @extern);
1380- public string[] category_ids = { "personal", "hardware", "network", "system" };
1381- public string[] category_names = { N_("Personal"), N_("Hardware"), N_("Network and Wireless"), N_("System") };
1382-
1383- int ITEM_WIDTH = 96;
1384- int ITEM_PADDING = 10;
1385+ Gtk.Grid personal_grid;
1386+ Gtk.Grid hardware_grid;
1387+ Gtk.Grid network_grid;
1388+ Gtk.Grid system_grid;
1389+
1390+ public Gtk.IconView personal_iconview;
1391+ public Gtk.IconView hardware_iconview;
1392+ public Gtk.IconView network_iconview;
1393+ public Gtk.IconView system_iconview;
1394
1395 public CategoryView () {
1396- for (int i = 0; i < category_ids.length; i++) {
1397- var store = new Gtk.ListStore (5, typeof (Gdk.Pixbuf), typeof (string),
1398- typeof(string), typeof(bool), typeof(string));
1399- store.set_sort_column_id (1, Gtk.SortType.ASCENDING);
1400-
1401- var category_label = new Gtk.Label (_(category_names[i]));
1402- var fg_css = new Gtk.CssProvider ();
1403-
1404- try {
1405- fg_css.load_from_data ("*{
1406- color: shade (@bg_color, 0.4);
1407- font: open sans 11;
1408- font-weight: 600;
1409- text-shadow: 0 1px alpha (#fff, 0.6);
1410- }", -1);
1411- } catch (Error e) { warning (e.message); }
1412-
1413+ setup_category (Switchboard.Plug.Category.PERSONAL, 0);
1414+ setup_category (Switchboard.Plug.Category.HARDWARE, 1);
1415+ setup_category (Switchboard.Plug.Category.NETWORK, 2);
1416+ setup_category (Switchboard.Plug.Category.SYSTEM, 3);
1417+ }
1418+
1419+ private void setup_category (Switchboard.Plug.Category category, int i) {
1420+ var category_label = new Gtk.Label (get_category_name (category));
1421+ var fg_css = new Gtk.CssProvider ();
1422+
1423+ try {
1424+ fg_css.load_from_data ("*{
1425+ color: shade (@bg_color, 0.4);
1426+ font: open sans 11;
1427+ font-weight: 600;
1428+ text-shadow: 0 1px alpha (#fff, 0.6);
1429+ }", -1);
1430 category_label.get_style_context ().add_provider (fg_css, 20000);
1431- category_label.margin_left = 12;
1432- category_label.margin_right = 8;
1433- var filtered = new Gtk.TreeModelFilter (store, null);
1434- filtered.set_visible_column(3);
1435- filtered.refilter ();
1436-
1437- var category_plugs = new Gtk.IconView.with_model (filtered);
1438- category_plugs.set_item_width (ITEM_WIDTH);
1439- category_plugs.set_text_column (1);
1440- category_plugs.set_pixbuf_column (0);
1441- category_plugs.set_hexpand (true);
1442- category_plugs.selection_changed.connect (() => on_selection_changed (category_plugs, filtered));
1443-
1444- (category_plugs.get_cells ().nth_data (0) as Gtk.CellRendererText).wrap_mode = Pango.WrapMode.WORD;
1445- (category_plugs.get_cells ().nth_data (0) as Gtk.CellRendererText).ellipsize_set = true;
1446-
1447- var bg_css = new Gtk.CssProvider ();
1448- try {
1449- bg_css.load_from_data ("*{background-color:@background_color;}", -1);
1450- } catch (Error e) { warning (e.message); }
1451+ } catch (Error e) {
1452+ critical (e.message);
1453+ }
1454+
1455+ category_label.margin_left = 12;
1456+ category_label.margin_right = 8;
1457+ category_label.xalign = (float) 0.02;
1458+ category_label.use_markup = true;
1459+
1460+ var category_plugs = setup_icon_view ();
1461+
1462+ var bg_css = new Gtk.CssProvider ();
1463+ try {
1464+ bg_css.load_from_data ("*{background-color:@background_color;}", -1);
1465 category_plugs.get_style_context ().add_provider (bg_css, 20000);
1466- category_label.xalign = (float) 0.02;
1467-
1468- var grid = new Gtk.Grid ();
1469- category_label.use_markup = true;
1470-
1471- // Always add a Seperator
1472- var h_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
1473- h_separator.set_hexpand (true);
1474- h_separator.margin_right = 12;
1475- grid.attach (category_label, 0, 0, 1, 1);
1476- grid.attach (h_separator, 1, 0, 1, 1); // expand, fill, padding´
1477-
1478- grid.attach (category_plugs, 0, 1, 2, 1);
1479-
1480- category_labels[category_ids[i]] = grid;
1481- category_store[category_ids[i]] = store;
1482- category_views[category_ids[i]] = category_plugs;
1483-
1484- attach (grid, 0, i, 1, 1);
1485- }
1486- }
1487-
1488- public void add_plug (Gee.HashMap<string, string> plug) {
1489-
1490- Gtk.TreeIter root;
1491- string plug_down = plug["category"].down ();
1492-
1493- if (!(plug_down in category_ids)) {
1494- warning (_("Keyfile \"%s\" contains an invalid category: \"%s\", and will not be added"),
1495- plug["title"], plug["category"]);
1496+ } catch (Error e) {
1497+ critical (e.message);
1498+ }
1499+
1500+ var grid = new Gtk.Grid ();
1501+
1502+ // Always add a Seperator
1503+ var h_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
1504+ h_separator.set_hexpand (true);
1505+ h_separator.margin_right = 12;
1506+ grid.attach (category_label, 0, 0, 1, 1);
1507+ grid.attach (h_separator, 1, 0, 1, 1);
1508+
1509+ grid.attach (category_plugs, 0, 1, 2, 1);
1510+ switch (category) {
1511+ case Switchboard.Plug.Category.PERSONAL:
1512+ personal_iconview = category_plugs;
1513+ personal_grid = grid;
1514+ break;
1515+ case Switchboard.Plug.Category.HARDWARE:
1516+ hardware_iconview = category_plugs;
1517+ hardware_grid = grid;
1518+ break;
1519+ case Switchboard.Plug.Category.NETWORK:
1520+ network_iconview = category_plugs;
1521+ network_grid = grid;
1522+ break;
1523+ case Switchboard.Plug.Category.SYSTEM:
1524+ system_iconview = category_plugs;
1525+ system_grid = grid;
1526+ break;
1527+ }
1528+
1529+ attach (grid, 0, i, 1, 1);
1530+ }
1531+
1532+ public void load_default_plugs () {
1533+ var plugsmanager = Switchboard.PlugsManager.get_default ();
1534+ foreach (var plug in plugsmanager.get_plugs ()) {
1535+ plug.visibility_changed.connect (() => plug_visibility_changed (plug));
1536+ if (plug.can_show == true) {
1537+ add_plug (plug);
1538+ }
1539+ }
1540+
1541+ plugsmanager.plug_added.connect ( (plug) => {
1542+ plug.visibility_changed.connect (() => plug_visibility_changed (plug));
1543+ add_plug (plug);
1544+ });
1545+ }
1546+
1547+ private Gtk.IconView setup_icon_view () {
1548+ var store = new Gtk.ListStore (Columns.N_COLUMNS, typeof (Gdk.Pixbuf), typeof (string),
1549+ typeof(string), typeof(bool), typeof(Switchboard.Plug));
1550+ store.set_sort_column_id (1, Gtk.SortType.ASCENDING);
1551+ store.set_sort_column_id (1, Gtk.SortType.ASCENDING);
1552+
1553+ var filtered = new Gtk.TreeModelFilter (store, null);
1554+ filtered.set_visible_column (3);
1555+ filtered.refilter ();
1556+
1557+ var category_plugs = new Gtk.IconView.with_model (filtered);
1558+ category_plugs.set_item_width (ITEM_WIDTH);
1559+ category_plugs.set_text_column (Columns.TEXT);
1560+ category_plugs.set_pixbuf_column (Columns.ICON);
1561+ category_plugs.set_tooltip_column (Columns.DESCRIPTION);
1562+ category_plugs.set_hexpand (true);
1563+ category_plugs.selection_changed.connect (() => on_selection_changed (category_plugs, filtered));
1564+ var cellrenderer = (Gtk.CellRendererText)category_plugs.get_cells ().nth_data (0);
1565+ cellrenderer.wrap_mode = Pango.WrapMode.WORD;
1566+ cellrenderer.ellipsize_set = true;
1567+
1568+ return category_plugs;
1569+ }
1570+
1571+ private void plug_visibility_changed (Switchboard.Plug plug) {
1572+ if (plug.can_show == true) {
1573+ add_plug (plug);
1574+ }
1575+ }
1576+
1577+ public void add_plug (Switchboard.Plug plug) {
1578+ if (plug.can_show == false)
1579+ return;
1580+ Gtk.TreeIter root;
1581+ Gtk.TreeModelFilter model_filter;
1582+
1583+ switch (plug.category) {
1584+ case Switchboard.Plug.Category.PERSONAL:
1585+ model_filter = (Gtk.TreeModelFilter)personal_iconview.get_model ();
1586+ personal_grid.show_all ();
1587+ break;
1588+ case Switchboard.Plug.Category.HARDWARE:
1589+ model_filter = (Gtk.TreeModelFilter)hardware_iconview.get_model ();
1590+ hardware_grid.show_all ();
1591+ break;
1592+ case Switchboard.Plug.Category.NETWORK:
1593+ model_filter = (Gtk.TreeModelFilter)network_iconview.get_model ();
1594+ network_grid.show_all ();
1595+ break;
1596+ case Switchboard.Plug.Category.SYSTEM:
1597+ model_filter = (Gtk.TreeModelFilter)system_iconview.get_model ();
1598+ system_grid.show_all ();
1599+ break;
1600+ default:
1601 return;
1602- }
1603-
1604- Gdk.Pixbuf icon_pixbuf = null;
1605- try {
1606- icon_pixbuf = theme.load_icon (plug["icon"], 32, Gtk.IconLookupFlags.GENERIC_FALLBACK);
1607- } catch {
1608- warning(_("Unable to load plug %s's icon: %s"), plug["title"], plug["icon"]);
1609- return; // FIXME: if we get no icon, we probably dont want that one..
1610- }
1611- category_store[plug_down].append (out root);
1612-
1613- category_store[plug_down].set (root, 0, icon_pixbuf, 1, plug["title"], 2, plug["exec"],
1614- 3, true, 4, plug["extern"]);
1615- category_labels[plug_down].show_all ();
1616- category_views[plug_down].show_all ();
1617-
1618+ }
1619+
1620+ var store = model_filter.child_model as Gtk.ListStore;
1621+ Gdk.Pixbuf icon_pixbuf = null;
1622+ try {
1623+ // FIXME: if we get no icon, we probably dont want that one…
1624+ icon_pixbuf = theme.load_icon (plug.icon, 32, Gtk.IconLookupFlags.GENERIC_FALLBACK);
1625+ } catch {
1626+ critical ("Unable to load plug %s's icon: %s", plug.display_name, plug.icon);
1627+ return;
1628+ }
1629+
1630+ store.append (out root);
1631+ store.set (root, Columns.ICON, icon_pixbuf, Columns.TEXT, plug.display_name,
1632+ Columns.DESCRIPTION, plug.description, Columns.VISIBLE, true, Columns.PLUG, plug);
1633+ unowned SwitchboardApp app = (SwitchboardApp) GLib.Application.get_default ();
1634+
1635+ if (Switchboard.PlugsManager.get_default ().has_plugs ()) {
1636+ app.search_box.sensitive = true;
1637+ filter_plugs (app.search_box.get_text ());
1638+
1639+ if (plug_to_open != null) {
1640+ if (plug_to_open.has_suffix (plug.code_name)) {
1641+ app.current_plug = plug;
1642+ plug_to_open = null;
1643+ }
1644+ }
1645+
1646+ app.update_libunity_quicklist ();
1647+ }
1648 }
1649
1650- public void filter_plugs (string filter, SwitchboardApp switchboard) {
1651-
1652+ public void filter_plugs (string filter) {
1653+
1654 var any_found = false;
1655- foreach (string category in category_ids) {
1656-
1657- var store = category_store[category];
1658- var container = category_labels[category];
1659-
1660- int shown = 0;
1661-
1662- store.foreach ((model, path, iter) => {
1663- string title;
1664-
1665- store.get (iter, 1, out title);
1666-
1667- if (filter.down () in title.down ()) {
1668- store.set_value (iter, 3, true);
1669- shown ++;
1670- } else {
1671- store.set_value (iter, 3, false);
1672- }
1673-
1674+
1675+ if (search_by_category (filter, Switchboard.Plug.Category.PERSONAL))
1676+ any_found = true;
1677+ if (search_by_category (filter, Switchboard.Plug.Category.HARDWARE))
1678+ any_found = true;
1679+ if (search_by_category (filter, Switchboard.Plug.Category.NETWORK))
1680+ any_found = true;
1681+ if (search_by_category (filter, Switchboard.Plug.Category.SYSTEM))
1682+ any_found = true;
1683+
1684+ unowned SwitchboardApp app = (SwitchboardApp) GLib.Application.get_default ();
1685+ if (!any_found) {
1686+ app.show_alert (_("No settings found"), _("Try changing your search terms"), Gtk.MessageType.INFO);
1687+ } else {
1688+ app.hide_alert ();
1689+ }
1690+ }
1691+
1692+ private bool search_by_category (string filter, Plug.Category category) {
1693+
1694+ Gtk.TreeModelFilter model_filter;
1695+ Gtk.Widget grid;
1696+
1697+ switch (category) {
1698+ case Switchboard.Plug.Category.PERSONAL:
1699+ model_filter = (Gtk.TreeModelFilter)personal_iconview.get_model ();
1700+ grid = personal_grid;
1701+ break;
1702+ case Switchboard.Plug.Category.HARDWARE:
1703+ model_filter = (Gtk.TreeModelFilter)hardware_iconview.get_model ();
1704+ grid = hardware_grid;
1705+ break;
1706+ case Switchboard.Plug.Category.NETWORK:
1707+ model_filter = (Gtk.TreeModelFilter)network_iconview.get_model ();
1708+ grid = network_grid;
1709+ break;
1710+ case Switchboard.Plug.Category.SYSTEM:
1711+ model_filter = (Gtk.TreeModelFilter)system_iconview.get_model ();
1712+ grid = system_grid;
1713+ break;
1714+ default:
1715 return false;
1716- });
1717-
1718- if (shown == 0) {
1719- container.hide ();
1720+ }
1721+
1722+ var store = model_filter.child_model as Gtk.ListStore;
1723+ int shown = 0;
1724+ store.foreach ((model, path, iter) => {
1725+ string title;
1726+
1727+ store.get (iter, Columns.TEXT, out title);
1728+
1729+ if (filter.down () in title.down ()) {
1730+ store.set_value (iter, Columns.VISIBLE, true);
1731+ shown++;
1732 } else {
1733- any_found = true;
1734- container.show ();
1735+ store.set_value (iter, Columns.VISIBLE, false);
1736 }
1737- }
1738- if (!any_found) {
1739- switchboard.show_alert (_("No settings found"), _("Try changing your search terms"), Gtk.MessageType.INFO);
1740+
1741+ return false;
1742+ });
1743+
1744+ if (shown == 0) {
1745+ grid.hide ();
1746+ return false;
1747 } else {
1748- switchboard.hide_alert ();
1749+ grid.show_all ();
1750+ return true;
1751 }
1752 }
1753
1754- public void recalculate_columns (int width) {
1755-
1756- foreach (var view in category_views.values) {
1757- view.set_columns (width / (ITEM_WIDTH + ITEM_PADDING * 2));
1758- }
1759+ public void recalculate_columns () {
1760+ int columns = personal_iconview.get_columns ();
1761+ columns = int.max (columns, hardware_iconview.get_columns ());
1762+ columns = int.max (columns, network_iconview.get_columns ());
1763+ columns = int.max (columns, system_iconview.get_columns ());
1764+ personal_iconview.set_columns (columns);
1765+ hardware_iconview.set_columns (columns);
1766+ network_iconview.set_columns (columns);
1767+ system_iconview.set_columns (columns);
1768 }
1769
1770 private void on_selection_changed (Gtk.IconView view, Gtk.TreeModelFilter store) {
1771-
1772- GLib.Value title;
1773- GLib.Value executable;
1774- GLib.Value @extern;
1775+ GLib.Value plug;
1776 Gtk.TreeIter selected_plug;
1777-
1778+
1779 var selected = view.get_selected_items ();
1780 var item = selected.nth_data (0);
1781
1782@@ -180,14 +310,26 @@
1783 return;
1784
1785 store.get_iter (out selected_plug, item);
1786- store.get_value (selected_plug, 1, out title);
1787- store.get_value (selected_plug, 2, out executable);
1788- store.get_value (selected_plug, 4, out @extern);
1789+ store.get_value (selected_plug, Columns.PLUG, out plug);
1790
1791- plug_selected (title.get_string (), executable.get_string (), @extern.get_string () == "1");
1792+ plug_selected ((Switchboard.Plug) plug.get_object ());
1793
1794 view.unselect_path (item);
1795 }
1796+
1797+ public static string? get_category_name (Switchboard.Plug.Category category) {
1798+ switch (category) {
1799+ case Plug.Category.PERSONAL:
1800+ return _("Personal");
1801+ case Plug.Category.HARDWARE:
1802+ return _("Hardware");
1803+ case Plug.Category.NETWORK:
1804+ return _("Network and Wireless");
1805+ case Plug.Category.SYSTEM:
1806+ return _("System");
1807+ }
1808+
1809+ return null;
1810+ }
1811 }
1812-}
1813-
1814+}
1815\ No newline at end of file
1816
1817=== modified file 'src/EmbeddedAlert.vala'
1818--- src/EmbeddedAlert.vala 2013-01-08 15:21:51 +0000
1819+++ src/EmbeddedAlert.vala 2014-01-02 20:30:11 +0000
1820@@ -124,7 +124,6 @@
1821 case Gtk.MessageType.WARNING:
1822 image.set_from_icon_name ("dialog-warning", Gtk.IconSize.DIALOG);
1823 break;
1824- break;
1825 case Gtk.MessageType.INFO:
1826 image.set_from_icon_name ("dialog-information", Gtk.IconSize.DIALOG);
1827 break;
1828
1829=== removed file 'src/Resources.vala'
1830--- src/Resources.vala 2013-01-08 15:21:51 +0000
1831+++ src/Resources.vala 1970-01-01 00:00:00 +0000
1832@@ -1,15 +0,0 @@
1833-namespace Switchboard {
1834-
1835- public const string APP_TITLE = _("System Settings");
1836- public const string COPYRIGHT = "Copyright (C) 2011-2012 Avi Romanoff";
1837- public const string WEBSITE = "https://launchpad.net/switchboard";
1838- public const string VERSION = "0.9";
1839- public const string[] AUTHORS = {"Avi Romanoff <aviromanoff@gmail.com>",
1840- null};
1841- public const string ERRDOMAIN = "switchboard";
1842- public const string APP_ICON = "preferences-desktop";
1843- public const string BUG_URL = "https://bugs.launchpad.net/switchboard";
1844- public const string HELP_URL = "https://answers.launchpad.net/switchboard";
1845- public const string TRANSLATE_URL = "https://translations.launchpad.net/switchboard";
1846-
1847-}
1848
1849=== modified file 'src/Switchboard.vala'
1850--- src/Switchboard.vala 2013-12-03 13:44:13 +0000
1851+++ src/Switchboard.vala 2014-01-02 20:30:11 +0000
1852@@ -17,75 +17,139 @@
1853
1854 namespace Switchboard {
1855
1856- static string plug_to_open;
1857-
1858- [DBus (name = "org.elementary.switchboard")]
1859+ static const OptionEntry[] entries = {
1860+ { "open-plug", 'o', 0, OptionArg.STRING, ref plug_to_open, N_("Open a plug"), "PLUG_NAME" },
1861+ { null }
1862+ };
1863+
1864+ private static string? plug_to_open = null;
1865+
1866+ public static int main (string[] args) {
1867+
1868+ Gtk.init (ref args);
1869+
1870+ var context = new OptionContext("");
1871+ context.add_main_entries(entries, "switchboard ");
1872+ context.add_group(Gtk.get_option_group(true));
1873+ try {
1874+ context.parse(ref args);
1875+ } catch(Error e) { warning (e.message); }
1876+ var app = new SwitchboardApp ();
1877+
1878+ return app.run (args);
1879+ }
1880+
1881 public class SwitchboardApp : Granite.Application {
1882+ private Gtk.Window main_window;
1883+ private Gtk.Stack stack;
1884+ private Gtk.HeaderBar headerbar;
1885+
1886+ private Granite.Widgets.EmbeddedAlert alert_view;
1887+ private Gtk.ScrolledWindow category_scrolled;
1888+ private Switchboard.NavigationButton navigation_button;
1889+ private Switchboard.CategoryView category_view;
1890+
1891+ private Gee.LinkedList <string> loaded_plugs;
1892+ private string all_settings_label = _("All Settings");
1893+
1894+ public Switchboard.Plug current_plug;
1895+ public Gtk.SearchEntry search_box { public get; private set; }
1896
1897 construct {
1898 application_id = "org.elementary.Switchboard";
1899 program_name = "Switchboard";
1900- app_years = "2011-2012";
1901+ app_years = "2011-2013";
1902 exec_name = "switchboard";
1903 app_launcher = exec_name+".desktop";
1904
1905- build_version = VERSION;
1906- app_icon = APP_ICON;
1907- main_url = WEBSITE;
1908- bug_url = BUG_URL;
1909- help_url = HELP_URL;
1910- translate_url = TRANSLATE_URL;
1911- about_authors = AUTHORS;
1912+ build_version = "2.0";
1913+ app_icon = "preferences-desktop";
1914+ main_url = "https://launchpad.net/switchboard";
1915+ bug_url = "https://bugs.launchpad.net/switchboard";
1916+ help_url = "https://answers.launchpad.net/switchboard";
1917+ translate_url = "https://translations.launchpad.net/switchboard";
1918+ about_authors = {"Avi Romanoff <aviromanoff@gmail.com>", "Corentin Noël <tintou@mailoo.org>", null};
1919
1920 about_license_type = Gtk.License.GPL_3_0;
1921 }
1922
1923- // Chrome widgets
1924- Gtk.ProgressBar progress_bar;
1925- Gtk.Label progress_label;
1926- Gtk.SearchEntry search_box;
1927- Gtk.Toolbar toolbar;
1928- Switchboard.NavigationButton navigation_button;
1929- // Public so we can hide it after show_all()
1930- public Gtk.ToolItem progress_toolitem;
1931- // These two wrap the progress bar
1932- Gtk.ToolItem lspace = new Gtk.ToolItem ();
1933- Gtk.ToolItem rspace = new Gtk.ToolItem ();
1934-
1935- Gtk.Spinner loading;
1936-
1937- Gtk.Window main_window;
1938-
1939- // Content area widgets
1940- Gtk.Socket socket;
1941- Gtk.Grid grid;
1942- Granite.Widgets.EmbeddedAlert alert_view;
1943- Gtk.ScrolledWindow scrollable_view;
1944- Switchboard.CategoryView category_view;
1945-
1946- // Plug data
1947- bool socket_shown;
1948- Gee.HashMap<string, string> current_plug = new Gee.HashMap<string, string>();
1949- Gee.HashMap<string, string>[] plugs;
1950-
1951- string[] plug_places = {"/usr/share/plugs/",
1952- "/usr/lib/plugs/",
1953- "/usr/local/share/plugs/",
1954- "/usr/local/lib/plugs/"};
1955- string search_box_buffer = "";
1956-
1957- private const string[] SUPPORTED_GETTEXT_DOMAINS_KEYS = {"X-Ubuntu-Gettext-Domain", "X-GNOME-Gettext-Domain"};
1958-
1959- string all_settings_label = _("All Settings");
1960-
1961- public SwitchboardApp () { }
1962-
1963- void build () {
1964+ public override void activate () {
1965+ // If app is already running, present the current window.
1966+ if (get_windows () != null) {
1967+ get_windows ().data.present ();
1968+ return;
1969+ }
1970+
1971+ if (DEBUG)
1972+ Granite.Services.Logger.DisplayLevel = Granite.Services.LogLevel.DEBUG;
1973+ else
1974+ Granite.Services.Logger.DisplayLevel = Granite.Services.LogLevel.INFO;
1975+
1976+ loaded_plugs = new Gee.LinkedList <string> ();
1977+ Switchboard.PlugsManager.get_default ();
1978+ build ();
1979+ category_view.load_default_plugs ();
1980+ if (current_plug != null)
1981+ load_plug (current_plug);
1982+
1983+ Gtk.main ();
1984+ }
1985+
1986+ public void hide_alert () {
1987+ stack.set_visible_child (category_scrolled);
1988+ }
1989+
1990+ public void show_alert (string primary_text, string secondary_text, Gtk.MessageType type) {
1991+ alert_view.set_alert (primary_text, secondary_text, null, true, type);
1992+ stack.set_visible_child (alert_view);
1993+ }
1994+
1995+ public void load_plug (Switchboard.Plug plug) {
1996+ if (!loaded_plugs.contains (plug.code_name)) {
1997+ stack.add_named (plug.get_widget (), plug.code_name);
1998+ loaded_plugs.add (plug.code_name);
1999+ }
2000+
2001+ // Launch plug's executable
2002+ navigation_button.set_sensitive (true);
2003+ navigation_button.set_text (all_settings_label);
2004+ navigation_button.show ();
2005+ headerbar.subtitle = plug.display_name;
2006+ current_plug = plug;
2007+ switch_to_plug (plug);
2008+ }
2009+
2010+ // Updates items in quicklist menu using the Unity quicklist api.
2011+ public void update_libunity_quicklist () {
2012+ var launcher = Unity.LauncherEntry.get_for_desktop_id (app_launcher);
2013+ var quicklist = new Dbusmenu.Menuitem ();
2014+
2015+ var personal_item = add_quicklist_for_category (Switchboard.Plug.Category.PERSONAL);
2016+ if (personal_item != null)
2017+ quicklist.child_append (personal_item);
2018+
2019+ var hardware_item = add_quicklist_for_category (Switchboard.Plug.Category.HARDWARE);
2020+ if (hardware_item != null)
2021+ quicklist.child_append (hardware_item);
2022+
2023+ var network_item = add_quicklist_for_category (Switchboard.Plug.Category.NETWORK);
2024+ if (network_item != null)
2025+ quicklist.child_append (network_item);
2026+
2027+ var system_item = add_quicklist_for_category (Switchboard.Plug.Category.SYSTEM);
2028+ if (system_item != null)
2029+ quicklist.child_append (system_item);
2030+
2031+ if (personal_item != null && hardware_item != null && network_item != null && system_item != null)
2032+ launcher.quicklist = quicklist;
2033+ }
2034+
2035+ private void build () {
2036 main_window = new Gtk.Window();
2037
2038 // Set up defaults
2039- main_window.title = APP_TITLE;
2040- main_window.icon_name = APP_ICON;
2041+ main_window.title = program_name;
2042+ main_window.icon_name = app_icon;
2043
2044 // Set up window
2045 main_window.set_default_size (842, 475);
2046@@ -94,424 +158,112 @@
2047 main_window.destroy.connect (shut_down);
2048 setup_toolbar ();
2049
2050- // Set up socket
2051- socket = new Gtk.Socket ();
2052- socket.set_hexpand(true);
2053- socket.set_vexpand(true);
2054-
2055- socket.plug_removed.connect (() => {
2056- plug_closed ();
2057- return true;
2058- });
2059-
2060 // Set up accelerators (hotkeys)
2061 var accel_group = new Gtk.AccelGroup ();
2062 uint accel_key;
2063 Gdk.ModifierType accel_mod;
2064 var accel_flags = Gtk.AccelFlags.LOCKED;
2065- Gtk.accelerator_parse("<Control>q", out accel_key, out accel_mod);
2066- accel_group.connect(accel_key, accel_mod, accel_flags, () => {
2067- main_window.destroy();
2068- return true;
2069- });
2070+ Gtk.accelerator_parse ("<Control>q", out accel_key, out accel_mod);
2071 main_window.add_accel_group (accel_group);
2072-
2073- // ??? Why?
2074- current_plug["title"] = "";
2075- current_plug["executable"] = "";
2076+ accel_group.connect (accel_key, accel_mod, accel_flags, () => {
2077+ main_window.destroy ();
2078+ return true;
2079+ });
2080
2081 category_view = new Switchboard.CategoryView ();
2082- category_view.plug_selected.connect ((title, executable, @extern) => load_plug (title, executable, @extern));
2083+ category_view.plug_selected.connect ((plug) => load_plug (plug));
2084 category_view.margin_top = 12;
2085
2086- scrollable_view = new Gtk.ScrolledWindow (null, null);
2087+ category_scrolled = new Gtk.ScrolledWindow (null, null);
2088+ category_scrolled.add_with_viewport (category_view);
2089+ category_scrolled.set_vexpand (true);
2090
2091 // Set up UI
2092- grid = new Gtk.Grid ();
2093- grid.set_hexpand (true);
2094- grid.set_vexpand (true);
2095- grid.attach (toolbar, 0, 0, 1, 1);
2096- toolbar.set_hexpand (true);
2097-
2098 alert_view = new Granite.Widgets.EmbeddedAlert ();
2099 alert_view.set_vexpand (true);
2100- grid.attach (alert_view, 0, 2, 1, 1);
2101-
2102- main_window.add (grid);
2103- scrollable_view.add_with_viewport (category_view);
2104- scrollable_view.set_vexpand (true);
2105- grid.attach (scrollable_view, 0, 1, 1, 1);
2106-
2107+
2108+ stack = new Gtk.Stack ();
2109+ stack.expand = true;
2110+ stack.add_named (category_scrolled, "main");
2111+ stack.add_named (alert_view, "alert");
2112+ stack.set_visible_child (category_scrolled);
2113+
2114+ main_window.add (stack);
2115 main_window.set_application (this);
2116 main_window.show_all ();
2117+ navigation_button.hide ();
2118
2119 main_window.size_allocate.connect (() => {
2120- var width = main_window.get_allocated_width ();
2121- category_view.recalculate_columns (width);
2122- });
2123-
2124- navigation_button.hide ();
2125-
2126- foreach (var label in category_view.category_labels.values)
2127- label.hide ();
2128- foreach (var view in category_view.category_views.values)
2129- view.hide ();
2130-
2131- alert_view.hide();
2132-
2133- loading = new Gtk.Spinner ();
2134- loading.set_vexpand(true);
2135- loading.halign = Gtk.Align.CENTER;
2136- loading.valign = Gtk.Align.CENTER;
2137- loading.width_request = 72;
2138- loading.height_request = 72;
2139- loading.start ();
2140-
2141- grid.attach (socket, 0, 1, 1, 1);
2142- socket.hide ();
2143- grid.attach (loading, 0, 1, 1, 1);
2144- loading.hide ();
2145-
2146- var any_plugs = false;
2147-
2148- socket.plug_added.connect (() => {
2149- if (loading.visible) {
2150- loading.hide ();
2151- socket.show_all ();
2152- }
2153- });
2154-
2155- foreach (string place in plug_places)
2156- if (enumerate_plugs (place))
2157- any_plugs = true;
2158-
2159- if (!any_plugs) {
2160- show_alert(_("No settings found"), _("Install some and re-launch Switchboard"), Gtk.MessageType.WARNING);
2161+ category_view.recalculate_columns ();
2162+ });
2163+
2164+ if (Switchboard.PlugsManager.get_default ().has_plugs () == false) {
2165+ show_alert (_("No settings found"), _("Install some and re-launch Switchboard"), Gtk.MessageType.WARNING);
2166 search_box.sensitive = false;
2167 } else {
2168 update_libunity_quicklist ();
2169 }
2170-
2171- bool found = false;
2172- if (plug_to_open != null) {
2173- foreach (var plug in plugs) {
2174- if (plug["id"] == plug_to_open) {
2175- load_plug (plug["title"], plug["exec"], plug["extern"] == "1");
2176- found = true;
2177- }
2178- }
2179- if (!found) {
2180- critical ("Couldn't find %s among the loaded settings.", plug_to_open);
2181- }
2182- }
2183-
2184- foreach (var store in category_view.category_store.values) {
2185- store.foreach ((model, path, iter) => {
2186- store.set_value (iter, 3, true);
2187- return false;
2188- });
2189- }
2190-
2191- progress_toolitem.hide ();
2192- }
2193-
2194- void shut_down () {
2195- plug_closed ();
2196- }
2197-
2198- public void hide_alert () {
2199- alert_view.hide ();
2200- scrollable_view.show ();
2201- }
2202-
2203- public void show_alert (string primary_text, string secondary_text, Gtk.MessageType type) {
2204- alert_view.set_alert (primary_text, secondary_text, null, true, type);
2205- alert_view.show ();
2206- scrollable_view.hide ();
2207- }
2208-
2209- public void load_plug (string title, string executable, bool @extern) {
2210- debug ("Selected plug: title %s | executable %s", title, executable);
2211-
2212- // Launch plug's executable
2213- if (current_plug["title"] != title || !socket.visible) {
2214- try {
2215- // The plug is already selected
2216- debug(_("Closing plug \"%s\" in Switchboard controller..."), current_plug["title"]);
2217- plug_closed ();
2218-
2219- string[] cmd_exploded = (executable!=null)?executable.split (" "):null;
2220- GLib.Process.spawn_async (File.new_for_path (cmd_exploded[0]).get_parent ().
2221- get_path (), cmd_exploded, null, SpawnFlags.SEARCH_PATH, null, null);
2222-
2223- // ensure the button is sensitive; it might be the first plug loaded
2224- if (!@extern) {
2225- navigation_button.set_sensitive (true);
2226- navigation_button.set_text (all_settings_label);
2227- navigation_button.show ();
2228-
2229- current_plug["title"] = title;
2230- current_plug["executable"] = executable;
2231- switch_to_socket ();
2232- main_window.title = @"$APP_TITLE - $title";
2233- }
2234- } catch { warning(_("Failed to launch plug: title %s | executable %s"), title, executable); }
2235- } else {
2236- navigation_button.set_sensitive (true);
2237- navigation_button.set_text (all_settings_label);
2238- navigation_button.show ();
2239- }
2240-
2241- if (@extern) {
2242- switch_to_icons ();
2243- }
2244+ }
2245+
2246+ private void shut_down () {
2247+ Gtk.main_quit ();
2248 }
2249
2250 // Change Switchboard title back to "Switchboard"
2251- void reset_title () {
2252- main_window.title = APP_TITLE;
2253+ private void reset_title () {
2254+ headerbar.subtitle = null;
2255 }
2256
2257 // Handles clicking the navigation button
2258- void handle_navigation_button_clicked () {
2259- if (navigation_button.get_text () != current_plug["title"]) {
2260- switch_to_icons();
2261- navigation_button.set_text (current_plug["title"]);
2262+ private void handle_navigation_button_clicked () {
2263+ if (navigation_button.get_text () == all_settings_label) {
2264+ switch_to_icons ();
2265+ navigation_button.set_text (current_plug.display_name);
2266 } else {
2267- load_plug (current_plug["title"], current_plug["executable"], current_plug["extern"] == "1");
2268+ switch_to_plug (current_plug);
2269 navigation_button.set_text (all_settings_label);
2270 }
2271 }
2272
2273 // Switches to the socket view
2274- void switch_to_socket () {
2275- socket_shown = true;
2276+ private void switch_to_plug (Switchboard.Plug plug) {
2277+ stack.set_transition_type (Gtk.StackTransitionType.SLIDE_LEFT);
2278 search_box.sensitive = false;
2279-
2280- category_view.hide ();
2281- socket.hide ();
2282- loading.show_all ();
2283+ plug.shown ();
2284+ stack.set_visible_child_name (plug.code_name);
2285 }
2286
2287 // Switches back to the icons
2288- bool switch_to_icons () {
2289- socket.hide ();
2290- loading.hide ();
2291- category_view.show ();
2292-
2293- socket_shown = false;
2294+ private bool switch_to_icons () {
2295+ stack.set_transition_type (Gtk.StackTransitionType.SLIDE_RIGHT);
2296+ stack.set_visible_child (category_scrolled);
2297+ current_plug.hidden ();
2298
2299 // Reset state
2300 reset_title ();
2301- search_box.set_text("");
2302- search_box.sensitive = count_plugs() > 0;
2303- progress_label.set_text("");
2304- progress_bar.fraction = 0.0;
2305- progress_toolitem.visible = false;
2306-
2307- plug_closed ();
2308+ search_box.set_text ("");
2309+ search_box.sensitive = Switchboard.PlugsManager.get_default ().has_plugs ();
2310
2311 return true;
2312 }
2313
2314- // Loads in all of the plugs
2315- // Returns true if any were found,
2316- // false if none were.
2317- bool enumerate_plugs (string plug_root_dir) {
2318-
2319- // <keyfile's absolute path, keyfile's directory>
2320- List<string> keyfiles = find_plugs (plug_root_dir);
2321- if (keyfiles.length() == 0) {
2322- return false;
2323- } else {
2324- foreach (string keyfile in keyfiles) {
2325- KeyFile kf = new KeyFile();
2326-
2327- string head = File.new_for_path(keyfile).get_basename();
2328- string parent = File.new_for_path(keyfile).get_parent().get_path();
2329-
2330- Gee.HashMap<string, string> plug = new Gee.HashMap<string, string> ();
2331- try { kf.load_from_file(keyfile, KeyFileFlags.NONE);
2332- } catch (Error e) { warning("Couldn't load this keyfile, %s (path: %s)", e.message, keyfile); }
2333- plug["id"] = kf.get_start_group();
2334- try {
2335- var exec = kf.get_string (head, "exec");
2336- //if a path starts with a double slash, we take it as an absolute path
2337- if (exec.substring (0, 2) == "//") {
2338- exec = exec.substring (1);
2339- plug["extern"] = "1";
2340- } else {
2341- exec = Path.build_filename(parent, exec);
2342- plug["extern"] = "0";
2343- }
2344-
2345- plug["exec"] = exec;
2346- } catch (Error e) { warning("Couldn't read exec field in file %s, %s", keyfile, e.message); }
2347- try { plug["icon"] = kf.get_string (head, "icon");
2348- } catch (Error e) { warning("Couldn't read icon field in file %s, %s", keyfile, e.message); }
2349- try {
2350- plug["title"] = kf.get_locale_string (head, "title");
2351- string? textdomain = null;
2352- foreach (var domain_key in SUPPORTED_GETTEXT_DOMAINS_KEYS) {
2353- if (kf.has_key (head, domain_key)) {
2354- textdomain = kf.get_string (head, domain_key);
2355- break;
2356- }
2357- }
2358- if (textdomain != null)
2359- plug["title"] = GLib.dgettext (textdomain, plug["title"]).dup ();
2360- } catch (Error e) { warning("Couldn't read title field in file %s, %s", keyfile, e.message); }
2361- try { plug["category"] = kf.get_string (head, "category");
2362- } catch {
2363- plug["category"] = "other";
2364- }
2365- category_view.add_plug (plug);
2366- plugs += plug;
2367- }
2368- return true;
2369- }
2370- }
2371-
2372- // Checks if the file is a .plug file
2373- bool is_plug_file (string filename) {
2374- return (filename.down().has_suffix(".plug"));
2375- }
2376-
2377- // Find all .plug files
2378- List<string> find_plugs (string path, List<string>? keyfiles_list = null) {
2379- List<string>? keyfiles;
2380- if(keyfiles_list == null) {
2381- keyfiles = new List<string> ();
2382- } else {
2383- keyfiles = new List<string> ();
2384- foreach(var keyfile in keyfiles_list) {
2385- keyfiles.append(keyfile);
2386- }
2387- }
2388-
2389- var directory = File.new_for_path (path);
2390- if (!directory.query_exists ()) {
2391- return null;
2392- }
2393- try {
2394- var enumerator = directory.enumerate_children (
2395- FileAttribute.STANDARD_NAME + "," + FileAttribute.STANDARD_TYPE, 0);
2396- FileInfo file_info;
2397- while ((file_info = enumerator.next_file ()) != null) {
2398- string file_path = Path.build_filename(path, file_info.get_name());
2399- if (file_info.get_file_type() == GLib.FileType.REGULAR &&
2400- is_plug_file(file_info.get_name())) {
2401- keyfiles.append(file_path);
2402- } else if(file_info.get_file_type() == GLib.FileType.DIRECTORY) {
2403- keyfiles = find_plugs(file_path, keyfiles);
2404- }
2405- }
2406- } catch { warning(_(@"Unable to iterate over enumerated plug directory \"$path\"'s contents")); }
2407-
2408- return keyfiles;
2409- }
2410-
2411- // Counts how many plugs exist at the moment
2412- int count_plugs () {
2413-
2414- uint count = 0;
2415- foreach (string place in plug_places)
2416- count += find_plugs (place).length ();
2417- return (int) count;
2418- }
2419-
2420- /*
2421- D-Bus ONLY methods
2422- */
2423-
2424- public int get_socket_wid () {
2425-
2426- return ((int) socket.get_id ());
2427- }
2428-
2429- public signal void plug_closed ();
2430-
2431- public void progress_bar_set_visible (bool visibility) {
2432-
2433- progress_toolitem.set_visible(visibility);
2434- }
2435-
2436- public void progress_bar_set_text (string text) {
2437-
2438- progress_label.set_text(text);
2439- }
2440-
2441- public void progress_bar_set_fraction (double fraction) {
2442-
2443- progress_bar.fraction = fraction;
2444- }
2445-
2446- public void progress_bar_pulse () {
2447-
2448- progress_bar.pulse();
2449- }
2450-
2451- public signal void search_box_activated ();
2452-
2453- public signal void search_box_text_changed ();
2454-
2455- public void search_box_set_sensitive (bool sensitivity) {
2456- search_box.set_sensitive (sensitivity);
2457- }
2458-
2459- public void search_box_set_text (string text) {
2460-
2461- plug_closed();
2462- search_box.set_text (text);
2463- }
2464-
2465- public string search_box_get_text () {
2466-
2467- return search_box.get_text ();
2468- }
2469-
2470- /*
2471- End D-Bus ONLY methods
2472- */
2473-
2474 // Sets up the toolbar for the Switchboard app
2475- void setup_toolbar () {
2476-
2477+ private void setup_toolbar () {
2478 // Global toolbar widgets
2479- toolbar = new Gtk.Toolbar ();
2480- toolbar.get_style_context ().add_class ("primary-toolbar");
2481-
2482- // Spacing
2483- lspace.set_expand(true);
2484- rspace.set_expand(true);
2485-
2486- // Progressbar
2487- var progress_vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
2488- progress_label = new Gtk.Label ("");
2489- progress_label.set_use_markup(true);
2490- progress_bar = new Gtk.ProgressBar ();
2491- progress_toolitem = new Gtk.ToolItem ();
2492- progress_vbox.pack_start(progress_label, true, false, 0);
2493- progress_vbox.pack_end(progress_bar, false, false, 0);
2494- progress_toolitem.add(progress_vbox);
2495- progress_toolitem.set_expand(true);
2496+ headerbar = new Gtk.HeaderBar ();
2497+ headerbar.show_close_button = true;
2498+ headerbar.title = program_name;
2499+ main_window.set_titlebar (headerbar);
2500
2501 // Searchbar
2502 search_box = new Gtk.SearchEntry ();
2503- search_box.set_placeholder_text (_("Search Settings"));
2504- search_box.activate.connect (() => search_box_activated ());
2505-
2506- search_box.changed.connect (() => {
2507- category_view.filter_plugs (search_box.get_text (), this);
2508- search_box_text_changed ();
2509+ search_box.placeholder_text = _("Search Settings");
2510+ search_box.margin_right = 5;
2511+ search_box.sensitive = false;
2512+ search_box.changed.connect(() => {
2513+ category_view.filter_plugs(search_box.get_text ());
2514 });
2515
2516- search_box.sensitive = (count_plugs () > 0);
2517- search_box.margin = 5;
2518- var find_toolitem = new Gtk.ToolItem ();
2519- find_toolitem.add(search_box);
2520- find_toolitem.margin_right = 6;
2521-
2522 // Focus typing to the search bar
2523 main_window.key_press_event.connect ((event) => {
2524 // Don't focus if it is a modifier or if search_box is already focused.
2525@@ -524,107 +276,60 @@
2526 // Nav button
2527 navigation_button = new NavigationButton ();
2528 navigation_button.clicked.connect (handle_navigation_button_clicked);
2529- navigation_button.margin = 5;
2530+ navigation_button.sensitive = false;
2531
2532 // Add everything to the toolbar
2533-
2534- Gtk.ToolItem tool = new Gtk.ToolItem ();
2535- tool.add (navigation_button);
2536- toolbar.insert (tool, -1);
2537- toolbar.insert (lspace, -1);
2538- toolbar.insert (progress_toolitem, -1);
2539- toolbar.insert (rspace, -1);
2540- toolbar.insert (find_toolitem, -1);
2541+ headerbar.pack_start (navigation_button);
2542+ headerbar.pack_end (search_box);
2543 }
2544
2545- public override void activate () {
2546- // If app is already running, present the current window.
2547- if (get_windows () != null) {
2548- get_windows ().data.present ();
2549- return;
2550+ private Dbusmenu.Menuitem? add_quicklist_for_category (Switchboard.Plug.Category category) {
2551+ // Create menuitem for this category
2552+ var category_item = new Dbusmenu.Menuitem ();
2553+ category_item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, CategoryView.get_category_name (category));
2554+
2555+ Gtk.TreeModelFilter model_filter;
2556+ switch (category) {
2557+ case Switchboard.Plug.Category.PERSONAL:
2558+ model_filter = (Gtk.TreeModelFilter)category_view.personal_iconview.get_model ();
2559+ break;
2560+ case Switchboard.Plug.Category.HARDWARE:
2561+ model_filter = (Gtk.TreeModelFilter)category_view.hardware_iconview.get_model ();
2562+ break;
2563+ case Switchboard.Plug.Category.NETWORK:
2564+ model_filter = (Gtk.TreeModelFilter)category_view.network_iconview.get_model ();
2565+ break;
2566+ case Switchboard.Plug.Category.SYSTEM:
2567+ model_filter = (Gtk.TreeModelFilter)category_view.system_iconview.get_model ();
2568+ break;
2569+ default:
2570+ return null;
2571 }
2572
2573- build ();
2574- }
2575-
2576- // Updates items in quicklist menu using the Unity quicklist api.
2577- void update_libunity_quicklist () {
2578- // Fetch launcher
2579- var launcher = Unity.LauncherEntry.get_for_desktop_id (app_launcher);
2580- var quicklist = new Dbusmenu.Menuitem ();
2581-
2582- // Add menuitems for every category.
2583- for (int i = 0; i < category_view.category_names.length; i++) {
2584- // Create menuitem for this category
2585- var category_item = new Dbusmenu.Menuitem ();
2586- var category_name = category_view.category_names[i];
2587- category_item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, _(category_name));
2588-
2589- // Loop through every plug and add a quicklist item
2590- var category_id = category_view.category_ids[i];
2591- var category_store = category_view.category_store[category_id];
2592- category_store.foreach ((model, path, iter) => {
2593- string title, exec, @extern;
2594- category_store.get (iter, 1, out title, 2, out exec, 4, out @extern);
2595-
2596- var item = new Dbusmenu.Menuitem ();
2597- item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, title);
2598-
2599- // When item is clicked, open corresponding plug
2600- item.item_activated.connect (() => {
2601- load_plug (title, exec, @extern == "1");
2602- activate ();
2603- });
2604-
2605- // Add item to correct category
2606- category_item.child_append (item);
2607-
2608- return false;
2609+ var category_store = model_filter.child_model as Gtk.ListStore;
2610+ bool empty = true;
2611+
2612+ category_store.foreach ((model, path, iter) => {
2613+ Switchboard.Plug plug;
2614+ category_store.get (iter, CategoryView.Columns.PLUG, out plug);
2615+
2616+ var item = new Dbusmenu.Menuitem ();
2617+ item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, plug.display_name);
2618+
2619+ // When item is clicked, open corresponding plug
2620+ item.item_activated.connect (() => {
2621+ load_plug (plug);
2622+ activate ();
2623 });
2624
2625- quicklist.child_append (category_item);
2626- }
2627-
2628- launcher.quicklist = quicklist;
2629+ // Add item to correct category
2630+ category_item.child_append (item);
2631+ empty = false;
2632+
2633+ return false;
2634+ });
2635+
2636+ return (empty ? null : category_item);
2637 }
2638 }
2639-
2640- static const OptionEntry[] entries = {
2641- { "open-plug", 'o', 0, OptionArg.STRING, ref plug_to_open, N_("Open a plug"), "PLUG_NAME" },
2642- { null }
2643- };
2644-
2645- public static int main (string[] args) {
2646-
2647- var logger = new Granite.Services.Logger ();
2648- logger.initialize(APP_TITLE);
2649- logger.DisplayLevel = Granite.Services.LogLevel.INFO;
2650- message(_(@"Welcome to $APP_TITLE"));
2651- message(_(@"Version: $VERSION"));
2652- message(_("Report any issues/bugs you mind find to lp:switchboard"));
2653-
2654- Gtk.init (ref args);
2655-
2656- var context = new OptionContext("");
2657- context.add_main_entries(entries, "switchboard ");
2658- context.add_group(Gtk.get_option_group(true));
2659- try {
2660- context.parse(ref args);
2661- } catch(Error e) { warning (e.message); }
2662-
2663- // In the future, the plug_root_dir should be overridable by CLI flags.
2664- var switchboard_app = new SwitchboardApp ();
2665-
2666- GLib.Bus.own_name (BusType.SESSION, "org.elementary.switchboard",
2667- BusNameOwnerFlags.NONE,
2668- (conn) => {
2669- try {
2670- conn.register_object("/org/elementary/switchboard", switchboard_app);
2671- } catch (IOError e) { warning (e.message); }
2672- },
2673- () => {},
2674- () => {logger.notification(_("Switchboard already running. Exiting..")); Process.exit(1);});
2675-
2676- return switchboard_app.run (args);
2677- }
2678-}
2679+}
2680\ No newline at end of file
2681
2682=== removed directory 'vapi'
2683=== removed file 'vapi/config.vapi'
2684--- vapi/config.vapi 2011-06-23 05:56:29 +0000
2685+++ vapi/config.vapi 1970-01-01 00:00:00 +0000
2686@@ -1,9 +0,0 @@
2687-[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
2688-namespace Build {
2689- public const string DATADIR;
2690- public const string PKGDATADIR;
2691- public const string GETTEXT_PACKAGE;
2692- public const string RELEASE_NAME;
2693- public const string VERSION;
2694- public const string VERSION_INFO;
2695-}

Subscribers

People subscribed via source and target branches

to all changes: