summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-09-01 21:36:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-09-01 21:36:22 (GMT)
commit29ddd755496589e7e1f9e38697e44d3cfe64df5e (patch)
tree3db093a9082276adb96a1ce67d175ade067c0788
parente07a541d1dea13a19a587f2b97d12ed3443f235b (diff)
Added a welcome panel as plugin using Python.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@573 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog39
-rw-r--r--configure.ac1
-rw-r--r--plugins/pychrysa/pychrysa.c78
-rw-r--r--plugins/python/Makefile.am2
-rw-r--r--plugins/python/welcome/Makefile.am14
-rw-r--r--plugins/python/welcome/__init__.py4
-rw-r--r--plugins/python/welcome/binary.py40
-rw-r--r--plugins/python/welcome/board.py102
-rw-r--r--plugins/python/welcome/panel.py147
-rw-r--r--plugins/python/welcome/plugin.py36
-rw-r--r--plugins/python/welcome/tip.py146
-rw-r--r--plugins/python/welcome/tipoftheday.pngbin0 -> 10206 bytes
-rw-r--r--plugins/python/welcome/tipoftheday.xcfbin0 -> 17942 bytes
-rw-r--r--plugins/python/welcome/version.py107
-rw-r--r--plugins/python/welcome/website.py30
-rw-r--r--src/gui/menus/project.c2
-rw-r--r--src/gui/panels/Makefile.am3
-rw-r--r--src/gui/panels/panel.c58
-rw-r--r--src/gui/panels/welcome.c173
-rw-r--r--src/gui/panels/welcome.h65
20 files changed, 743 insertions, 304 deletions
diff --git a/ChangeLog b/ChangeLog
index 3fa796a..99b1f7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+15-09-01 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Add the new Makefile from the 'plugins/python/welcome' directory.
+
+ * plugins/pychrysa/pychrysa.c:
+ Provide the revision number and a way to access global objects.
+
+ * plugins/python/Makefile.am:
+ Add 'welcome' to SUBDIRS.
+
+ * plugins/python/welcome/binary.py:
+ * plugins/python/welcome/board.py:
+ * plugins/python/welcome/__init__.py:
+ * plugins/python/welcome/Makefile.am:
+ * plugins/python/welcome/panel.py:
+ * plugins/python/welcome/plugin.py:
+ * plugins/python/welcome/tipoftheday.png:
+ * plugins/python/welcome/tipoftheday.png:
+ * plugins/python/welcome/tipoftheday.xcf:
+ * plugins/python/welcome/tipoftheday.xcf:
+ * plugins/python/welcome/tip.py:
+ * plugins/python/welcome/version.py:
+ * plugins/python/welcome/website.py:
+ New entries: add a welcome panel as plugin using Python.
+
+ * src/gui/menus/project.c:
+ Register the menu loading new binary files.
+
+ * src/gui/panels/Makefile.am:
+ Remove the 'welcome.[ch]' files from libguipanels_la_SOURCES.
+
+ * src/gui/panels/panel.c:
+ Update code.
+
+ * src/gui/panels/welcome.c:
+ * src/gui/panels/welcome.h:
+ Deleted entries.
+
15-08-27 Cyrille Bagard <nocbos@gmail.com>
* plugins/pychrysa/gui/panels/panel.c:
diff --git a/configure.ac b/configure.ac
index a2ac711..d447047 100644
--- a/configure.ac
+++ b/configure.ac
@@ -289,6 +289,7 @@ AC_CONFIG_FILES([Makefile
plugins/python/apkfiles/Makefile
plugins/python/exectracer/Makefile
plugins/python/samples/Makefile
+ plugins/python/welcome/Makefile
plugins/readelf/Makefile
plugins/ropgadgets/Makefile
plugins/stackvars/Makefile
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index eafb358..c77553b 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -228,6 +228,7 @@ bool init_plugin(GPluginModule *plugin, GObject *ref)
#include <config.h>
+#include <common/cpp.h>
#include <common/environment.h>
#include <common/extstr.h>
#include <plugins/plugin-def.h>
@@ -245,12 +246,18 @@ bool init_plugin(GPluginModule *plugin, GObject *ref)
DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("PyChrysalide", "Provides bindings to Python", "0.1.0", PGA_PLUGIN_INIT);
+/* Fournit la révision du programme global. */
+static PyObject *py_chrysalide_revision(PyObject *, PyObject *);
+
/* Fournit la version du programme global. */
static PyObject *py_chrysalide_version(PyObject *, PyObject *);
/* Fournit la version du greffon pour Python. */
static PyObject *py_chrysalide_mod_version(PyObject *, PyObject *);
+/* Recherche et fournit si elle existe une valeur globale. */
+static PyObject *py_chrysalide_get_global_gobject(PyObject *, PyObject *);
+
/* Détermine si l'interpréteur lancé est celui pris en compte. */
static bool is_current_abi_suitable(void);
@@ -264,7 +271,7 @@ static bool load_python_plugins(GPluginModule *plugin, GObject *);
* Paramètres : self = NULL car méthode statique. *
* args = non utilisé ici. *
* *
-* Description : Fournit la version du programme global. *
+* Description : Fournit la révision du programme global. *
* *
* Retour : Numéro de révision. *
* *
@@ -272,6 +279,26 @@ static bool load_python_plugins(GPluginModule *plugin, GObject *);
* *
******************************************************************************/
+static PyObject *py_chrysalide_revision(PyObject *self, PyObject *args)
+{
+ return PyUnicode_FromString("r" XSTR(REVISION));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = NULL car méthode statique. *
+* args = non utilisé ici. *
+* *
+* Description : Fournit la version du programme global. *
+* *
+* Retour : Numéro de version. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
static PyObject *py_chrysalide_version(PyObject *self, PyObject *args)
{
char version[16];
@@ -297,7 +324,7 @@ static PyObject *py_chrysalide_version(PyObject *self, PyObject *args)
* *
* Description : Fournit la version du greffon pour Python. *
* *
-* Retour : Numéro de révision. *
+* Retour : Numéro de version. *
* *
* Remarques : - *
* *
@@ -316,6 +343,41 @@ static PyObject *py_chrysalide_mod_version(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* Paramètres : self = NULL car méthode statique. *
+* args = contient la clef d'accès à un champ particulier. *
+* *
+* Description : Recherche et fournit si elle existe une valeur globale. *
+* *
+* Retour : Object attaché à l'espace de référencement global ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_chrysalide_get_global_gobject(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ const char *key; /* Désignation du champ visé */
+ int ret; /* Bilan de lecture des args. */
+ void *data; /* Donnée quelconque */
+
+ ret = PyArg_ParseTuple(args, "s", &key);
+ if (!ret) Py_RETURN_NONE;
+
+ data = g_object_get_data(get_internal_ref(), key);
+ if (data == NULL) Py_RETURN_NONE;
+
+ if (!G_IS_OBJECT(data)) Py_RETURN_NONE;
+
+ result = pygobject_new(G_OBJECT(data));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Détermine si l'interpréteur lancé est celui pris en compte. *
@@ -410,13 +472,21 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
static PyMethodDef py_chrysalide_methods[] = {
+ { "revision", py_chrysalide_revision,
+ METH_NOARGS,
+ "revision(/)\n--\n\nProvide the revision number of Chrysalide."
+ },
{ "version", py_chrysalide_version,
METH_NOARGS,
- "version(/)\n--\n\nProvide the revision number of Chrysalide."
+ "version(/)\n--\n\nProvide the version number of Chrysalide."
},
{ "mod_version", py_chrysalide_mod_version,
METH_NOARGS,
- "mod_version(/)\n--\n\nProvide the revision number of Chrysalide module for Python."
+ "mod_version(/)\n--\n\nProvide the version number of Chrysalide module for Python."
+ },
+ { "get_global_gobject", py_chrysalide_get_global_gobject,
+ METH_VARARGS,
+ "get_global_gobject(key, /)\n--\n\nRetrieve if it exists a global GObject registered with the given key."
},
{ NULL }
diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am
index 7bb4122..f54e1be 100644
--- a/plugins/python/Makefile.am
+++ b/plugins/python/Makefile.am
@@ -1,2 +1,2 @@
-SUBDIRS = androperms apkfiles samples
+SUBDIRS = androperms apkfiles samples welcome
diff --git a/plugins/python/welcome/Makefile.am b/plugins/python/welcome/Makefile.am
new file mode 100644
index 0000000..7dd16fa
--- /dev/null
+++ b/plugins/python/welcome/Makefile.am
@@ -0,0 +1,14 @@
+
+welcomedir = $(datadir)/openida/plugins/python/welcome
+
+welcome_DATA = \
+ __init__.py \
+ binary.py \
+ board.py \
+ panel.py \
+ plugin.py \
+ tip.py \
+ version.py \
+ website.py \
+ tipoftheday.png \
+ tipoftheday.xcf
diff --git a/plugins/python/welcome/__init__.py b/plugins/python/welcome/__init__.py
new file mode 100644
index 0000000..00a76af
--- /dev/null
+++ b/plugins/python/welcome/__init__.py
@@ -0,0 +1,4 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from welcome.plugin import WelcomePlugin as AutoLoad
diff --git a/plugins/python/welcome/binary.py b/plugins/python/welcome/binary.py
new file mode 100644
index 0000000..a9b508d
--- /dev/null
+++ b/plugins/python/welcome/binary.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from welcome.board import SmallBoard
+from gi.repository import Gtk, Gdk
+import pychrysalide
+
+
+class NewBinary(SmallBoard):
+ """Encourage l'ouverture d'un (premier) binaire."""
+
+
+ def __init__(self):
+ """Construit le panneau avec son contenu."""
+
+ super(NewBinary, self).__init__()
+
+ self._menu_item = pychrysalide.get_global_gobject('mnu_project_add_binary')
+
+ msg = 'Analyse a new binary by clicking <a href="file:///#">here</a>.'
+
+ desc = Gtk.Label(msg, use_markup=True, wrap=True)
+ desc.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK)
+ desc.set_track_visited_links(False)
+ desc.connect('activate-link', self.on_link_activated)
+ self.add(desc)
+
+
+ def on_link_activated(self, uri, data):
+ """Lance l'action associée au lien représenté."""
+
+ self._menu_item.activate()
+
+ return True
+
+
+ def get_location(self):
+ """Fournit la localisation souhaitée pour la plache."""
+
+ return [ 0, 0, 1, 1 ]
diff --git a/plugins/python/welcome/board.py b/plugins/python/welcome/board.py
new file mode 100644
index 0000000..ebebbc3
--- /dev/null
+++ b/plugins/python/welcome/board.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from gi.repository import Gtk
+
+
+class SmallBoard(Gtk.EventBox):
+ """Représente une tuile de support pour le panneau de bienvenue."""
+
+
+ css = """
+
+#classic {
+
+ border-color: rgba(255, 255, 255, 0.2);
+ border-style: solid;
+ border-width: 1px;
+
+}
+
+#hover {
+
+ border-color: rgba(255, 255, 255, 0.6);
+ border-style: solid;
+ border-width: 1px;
+
+}
+"""
+
+
+ def __init__(self):
+ """Construit le panneau avec son contenu."""
+
+ super(SmallBoard, self).__init__()
+
+ #self.set_size_request(250, 150)
+ self.set_has_window(True)
+
+ self.props.opacity = 0.6
+
+ self._manager = None
+
+
+ def on_enter(self, widget, event):
+ """Réagit à un survol de la zone par la souris."""
+
+ self.set_name('hover')
+
+ self._manager.define_selected_area(self.get_allocation())
+
+ self.props.opacity = 1.0
+
+ return False
+
+
+ def on_leave(self, widget, event):
+ """Réagit à une sortie de la zone par la souris."""
+
+ self.set_name('classic')
+
+ if self._manager != None:
+ self._manager.define_selected_area(None)
+
+ self.props.opacity = 0.6
+
+ return False
+
+
+ def get_location(self):
+ """Fournit la localisation souhaitée pour la plache."""
+
+ pass
+
+
+ def attach(self, manager):
+ """Lie partiellement la plache à son support et suit les survols."""
+
+ child = self.get_child()
+
+ if child != None:
+
+ child.props.margin = 20
+
+ self.set_name('classic')
+
+ self._manager = manager
+
+
+ def track_children(widget, owner):
+
+ widget.connect('enter-notify-event', self.on_enter)
+ widget.connect('leave-notify-event', self.on_leave)
+
+ if isinstance(widget, Gtk.Container):
+
+ children = widget.get_children()
+
+ for child in children:
+ track_children(child, owner)
+
+
+ track_children(self, self)
diff --git a/plugins/python/welcome/panel.py b/plugins/python/welcome/panel.py
new file mode 100644
index 0000000..811f008
--- /dev/null
+++ b/plugins/python/welcome/panel.py
@@ -0,0 +1,147 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from welcome.binary import NewBinary
+from welcome.version import VersionChecker
+from welcome.website import WebInvitation
+from welcome.board import SmallBoard
+from welcome.tip import TipOfTheDay
+from gi.repository import GObject, Gtk, Gdk
+from pychrysalide.gui.panels import PanelItem
+
+
+class WelcomePanel(PanelItem):
+ """Display a welcome panel if nothing is open in the main part of the editor."""
+
+
+ def __init__(self):
+ """Initialize the Python instance of the panel."""
+
+ content = self._build_panel_content()
+
+ super(WelcomePanel, self).__init__('Welcome', 'First commands', content, 'M')
+
+
+ def _build_panel_content(self):
+ """Build content for the welcome panel."""
+
+ self._area = None
+
+ # Constitution du support principal
+
+ support = Gtk.Grid()
+
+ support.props.halign = Gtk.Align.CENTER
+ support.props.valign = Gtk.Align.CENTER
+ support.props.margin = 20
+
+ support.set_column_homogeneous(True)
+ support.set_row_homogeneous(True)
+ support.set_column_spacing(20)
+ support.set_row_spacing(20)
+
+ # Mise en place des différentes tuiles
+
+ cells = { }
+
+ for x in range(4):
+ for y in range(3):
+ cells[(x, y)] = False
+
+ tiles = [
+
+ NewBinary(),
+ VersionChecker(),
+ WebInvitation(),
+ TipOfTheDay()
+
+ ]
+
+ for t in tiles:
+
+ x, y, w, h = t.get_location()
+
+ for i in range(x, x + w):
+ for j in range(y, y + h):
+ assert(cells[(i, j)] == False)
+ cells[(i, j)] = True
+
+ t.attach(self)
+ support.attach(t, x, y, w, h)
+
+ for x in range(4):
+ for y in range(3):
+ if not cells[(x, y)]:
+ tile = SmallBoard()
+ tile.attach(self)
+ support.attach(tile, x, y, 1, 1)
+
+ # Charge les styles propres aux panneaux
+
+ style_provider = Gtk.CssProvider()
+
+ style_provider.load_from_data(SmallBoard.css.encode())
+
+ Gtk.StyleContext.add_provider_for_screen(
+ Gdk.Screen.get_default(),
+ style_provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
+ )
+
+
+ support.show_all()
+ return support
+
+
+ def define_selected_area(self, area):
+
+ self._area = area
+
+ ####
+ #self.queue_draw()
+
+
+ def draw_selected_area(self, widget, cr):
+
+
+ alloc = widget.get_allocation()
+
+
+
+
+ def draw_rounded2(cr, area, radius):
+ """ draws rectangles with rounded (circular arc) corners """
+ from math import pi
+ a,b,c,d=area
+ cr.arc(a + radius, c + radius, radius, 2*(pi/2), 3*(pi/2))
+ cr.arc(b - radius, c + radius, radius, 3*(pi/2), 4*(pi/2))
+ cr.arc(b - radius, d - radius, radius, 0*(pi/2), 1*(pi/2)) # ;o)
+ cr.arc(a + radius, d - radius, radius, 1*(pi/2), 2*(pi/2))
+ cr.rectangle(self._area.x, self._area.y, self._area.width, self._area.height)
+ cr.close_path()
+ cr.fill()
+
+
+ if self._area != None:
+ cr.set_source_rgba(0, 0, 0, 0.15)
+
+ border = 4
+
+ pts = ( self._area.x - border, self._area.x + self._area.width + border,
+ self._area.y - border, self._area.y + self._area.height + border )
+
+ #cr.save()
+
+ draw_rounded2(cr, pts, 16)
+
+ ctx = self.get_style_context()
+
+
+ Gtk.render_background(ctx, cr, 0, 20, 100, 100)
+ Gtk.render_background(ctx, cr, self._area.x, self._area.y, self._area.width, self._area.height)
+
+
+ #cr.restore()
+
+
+ return False
diff --git a/plugins/python/welcome/plugin.py b/plugins/python/welcome/plugin.py
new file mode 100644
index 0000000..8a9f9a2
--- /dev/null
+++ b/plugins/python/welcome/plugin.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pychrysalide import PluginModule
+from welcome.panel import WelcomePanel
+
+
+class WelcomePlugin(PluginModule):
+ """Interface graphique d'accueil."""
+
+
+ def get_interface(self):
+ """Provide the full plugin description."""
+
+ desc = {
+
+ 'name' : 'Welcome',
+ 'desc' : 'Introduce the software when no project is loaded',
+ 'version' : '0.1',
+
+ 'actions' : [ PluginModule.PGA_PLUGIN_INIT ]
+
+ }
+
+ return desc
+
+
+ def init(self, ref):
+ """Initialise l'extension."""
+
+ self._panel = WelcomePanel()
+
+ self._panel.dock()
+ self._panel.register()
+
+ return True
diff --git a/plugins/python/welcome/tip.py b/plugins/python/welcome/tip.py
new file mode 100644
index 0000000..1a57575
--- /dev/null
+++ b/plugins/python/welcome/tip.py
@@ -0,0 +1,146 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from welcome.board import SmallBoard
+from gi.repository import Gtk
+import random
+
+try:
+ import cairo
+ has_cairo = True
+ import os
+except:
+ has_cairo = False
+
+
+_tip_messages = [
+ "Message 1",
+ "Message 2",
+ "Message 3",
+ "Message 4",
+ "Message 5",
+ "Message 6"
+]
+
+assert(len(_tip_messages) > 0)
+
+
+class TipOfTheDay(SmallBoard):
+ """Présente une série d'astuces du jour."""
+
+
+ def __init__(self):
+ """Construit le panneau avec son contenu."""
+
+ super(TipOfTheDay, self).__init__()
+
+ box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
+ self.add(box)
+
+ # Barre de contrôle
+
+ toolbar = Gtk.Box(spacing=10)
+ toolbar.props.margin = 20
+ box.pack_end(toolbar, False, True, 0)
+
+ btn = Gtk.Button('Previous')
+ btn.connect('clicked', self.show_previous_message)
+ toolbar.pack_start(btn, False, True, 8)
+
+ btn = Gtk.Button('Next')
+ btn.connect('clicked', self.show_next_message)
+ toolbar.pack_start(btn, False, True, 8)
+
+ # Contenu de l'astuce courante
+
+ desc = Gtk.Label('', use_markup=True, wrap=True, xalign=0)
+ self._message = desc
+ desc.set_justify(Gtk.Justification.LEFT)
+ box.pack_end(desc, False, True, 0)
+
+ # Titre
+
+ desc = Gtk.Label("<b>Did you know?</b>", use_markup=True, wrap=True, xalign=0)
+ desc.set_justify(Gtk.Justification.LEFT)
+ box.pack_end(desc, False, True, 0)
+
+ # Image de fond, si possible
+
+ if has_cairo:
+
+ os.chdir(os.path.dirname(__file__))
+
+ self._img = cairo.ImageSurface.create_from_png('tipoftheday.png')
+
+ self.connect_after('draw', self.draw_background)
+
+ # Sélection du message courant
+
+ self._indexes = [i for i in range(len(_tip_messages))]
+ random.shuffle(self._indexes)
+
+ self._index = 0
+
+ self.show_message()
+
+
+ def draw_background(self, widget, cr):
+ """Dessine une image de fond pour les conseils."""
+
+ img_width = self._img.get_width()
+ img_height = self._img.get_height()
+
+ alloc = self.get_allocation()
+ target_height = alloc.height * 0.7
+
+ if img_height > target_height:
+
+ scale = float(target_height) / float(img_height)
+
+ cr.translate(alloc.width - img_width * scale - 10, 10)
+ cr.scale(scale, scale)
+
+ else:
+
+ cr.translate(alloc.width - img_width - 10, 10)
+
+ cr.set_source_surface(self._img)
+ cr.paint_with_alpha(0.6)
+
+
+ def show_message(self):
+ """Affiche un conseil du jour donné."""
+
+ selected = self._indexes[self._index]
+
+ msg = _tip_messages[selected]
+
+ self._message.set_markup(msg)
+
+
+ def show_previous_message(self, button):
+ """Affiche un conseil du jour précédent."""
+
+ if self._index == 0:
+ self._index = len(_tip_messages) - 1
+ else:
+ self._index = self._index - 1
+
+ self.show_message()
+
+
+ def show_next_message(self, button):
+ """Affiche un conseil du jour suivant."""
+
+ self._index = self._index + 1
+
+ if self._index == len(_tip_messages):
+ self._index = 0
+
+ self.show_message()
+
+
+ def get_location(self):
+ """Fournit la localisation souhaitée pour la plache."""
+
+ return [ 2, 1, 2, 2 ]
diff --git a/plugins/python/welcome/tipoftheday.png b/plugins/python/welcome/tipoftheday.png
new file mode 100644
index 0000000..12f017a
--- /dev/null
+++ b/plugins/python/welcome/tipoftheday.png
Binary files differ
diff --git a/plugins/python/welcome/tipoftheday.xcf b/plugins/python/welcome/tipoftheday.xcf
new file mode 100644
index 0000000..dc9cf06
--- /dev/null
+++ b/plugins/python/welcome/tipoftheday.xcf
Binary files differ
diff --git a/plugins/python/welcome/version.py b/plugins/python/welcome/version.py
new file mode 100644
index 0000000..37ba001
--- /dev/null
+++ b/plugins/python/welcome/version.py
@@ -0,0 +1,107 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from welcome.board import SmallBoard
+from gi.repository import Gtk
+import pychrysalide
+
+try:
+ import urllib3
+ has_urllib3 = True
+except:
+ has_urllib3 = False
+
+
+class VersionChecker(SmallBoard):
+ """Affichage des versions courante et disponible, ainsi que des conclusions associées."""
+
+
+ def __init__(self):
+ """Construit le panneau avec son contenu."""
+
+ super(VersionChecker, self).__init__()
+
+ current = pychrysalide.revision()
+
+ if has_urllib3:
+
+ lastest = self.get_lastest_version('community')
+ up2date = self.get_update_status(current, lastest)
+
+ if lastest != None and up2date != None:
+
+ msg = '''Your version is: <b>%s</b>
+
+Lastest version is: <b>%s</b>'''
+
+ caption = msg % (current, lastest if lastest != None else 'unknown')
+
+ if up2date:
+ caption = caption + '''
+
+Your software is <span color='green'><b>up-to-date</b></span>.'''
+ else:
+ caption = caption + '''
+
+Your software is <b><span color='red'>outdated</span></b>.'''
+
+ else:
+
+ msg = '''Your version is: <b>%s</b>
+
+An error occurred while dealing with revision numbers.'''
+
+ caption = msg % current
+
+ else:
+
+ msg = '''Your version is: <b>%s</b>
+
+To display the lastest available version, please install the <b>urllib3</b> package for Python.'''
+
+ caption = msg % current
+
+ desc = Gtk.Label(caption, use_markup=True, wrap=True)
+ desc.set_track_visited_links(False)
+ self.add(desc)
+
+
+ def get_lastest_version(self, category):
+ """Retrouve la dernière version disponible à partir du site officiel."""
+
+ lastest = None
+
+ http = urllib3.PoolManager()
+ request = http.request('GET', 'http://localhost/mediawiki/data/versions')
+
+ html = request.data.decode('utf-8')
+
+ request.release_conn()
+
+ available = html.split('\n')
+
+ for a in available:
+ desc = a.split('=')
+ if desc[0] == category:
+ lastest = desc[1]
+ break
+
+ return lastest
+
+
+ def get_update_status(self, current, lastest):
+ """Détermine le degré de mise à jour du système."""
+
+ if current[0] != 'r' or lastest[0] != 'r':
+ return None
+
+ cur_rev = int(current[1:])
+ last_rev = int(lastest[1:])
+
+ return (cur_rev >= last_rev)
+
+
+ def get_location(self):
+ """Fournit la localisation souhaitée pour la plache."""
+
+ return [ 2, 0, 1, 1 ]
diff --git a/plugins/python/welcome/website.py b/plugins/python/welcome/website.py
new file mode 100644
index 0000000..07c2016
--- /dev/null
+++ b/plugins/python/welcome/website.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from welcome.board import SmallBoard
+from gi.repository import Gtk, Gdk
+
+
+class WebInvitation(SmallBoard):
+ """Présente un lien rapide vers le site Web officiel."""
+
+
+ def __init__(self):
+ """Construit le panneau avec son contenu."""
+
+ super(WebInvitation, self).__init__()
+
+ msg = '''Get access to the online documentation and stay tuned by visiting the official website :
+
+<a href="http://0xdeadc0de.fr/chrysalide/">0xdeadc0de.fr/chrysalide</a>'''
+
+ desc = Gtk.Label(msg, use_markup=True, wrap=True)
+ desc.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK)
+ desc.set_track_visited_links(False)
+ self.add(desc)
+
+
+ def get_location(self):
+ """Fournit la localisation souhaitée pour la plache."""
+
+ return [ 3, 0, 1, 1 ]
diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c
index caf3f64..a68b137 100644
--- a/src/gui/menus/project.c
+++ b/src/gui/menus/project.c
@@ -87,7 +87,7 @@ GtkWidget *build_menu_project(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b
G_CALLBACK(mcb_project_add_shellcode), bar);
gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem);
- deepmenuitem = qck_create_menu_item(NULL, NULL, _("File"),
+ deepmenuitem = qck_create_menu_item(ref, "mnu_project_add_binary", _("File"),
G_CALLBACK(mcb_project_add_binary_file), bar);
gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem);
diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am
index 70cf597..4746210 100644
--- a/src/gui/panels/Makefile.am
+++ b/src/gui/panels/Makefile.am
@@ -9,8 +9,7 @@ libguipanels_la_SOURCES = \
panel.h panel.c \
regedit.h regedit.c \
strings.h strings.c \
- symbols.h symbols.c \
- welcome.h welcome.c
+ symbols.h symbols.c
libguipanels_la_LDFLAGS =
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 7f18fea..265fcca 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -38,7 +38,6 @@
#include "regedit.h"
#include "strings.h"
#include "symbols.h"
-#include "welcome.h"
#include "../../gtkext/easygtk.h"
#include "../../gtkext/gtkdockable-int.h"
#include "../../gtkext/gtkdockstation.h"
@@ -58,7 +57,6 @@ static GCallback _handler;
static gpointer _data;
/* Liste des panneaux en place. */
-static GPanelItem *_welcome = NULL;
static GPanelItem *_panels_list = NULL;
@@ -133,13 +131,6 @@ static void set_panel_node_size_request(const panel_node *, const GtkRequisition
-/* Surveille les ajouts dans la partie principale. */
-static void on_docking_to_main_panel(GtkDockStation *, GtkWidget *, gpointer);
-
-
-
-
-
/* Indique le type défini pour un élément destiné à un panneau. */
G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM,
@@ -465,12 +456,6 @@ void load_main_panels(GObject *ref)
{
GPanelItem *item; /* Panneau de base à charger */
- _welcome = create_welcome_panel(ref);
- g_panel_item_dock(_welcome);
-
- g_signal_connect(_nodes->station, "dock-widget",
- G_CALLBACK(on_docking_to_main_panel), NULL);
-
item = create_regedit_panel(ref);
g_panel_item_dock(item);
@@ -1154,46 +1139,3 @@ static void set_panel_node_size_request(const panel_node *node, const GtkRequisi
set_panel_node_size_request(node->second, ALLOC_2_REQ(&allocation));
}
-
-
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* MECANISMES DE PLACEMENT DES PANNEAUX */
-/* ---------------------------------------------------------------------------------- */
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : station = base d'accueil pour composants divers. *
-* widget = composant rajouté à l'ensemble. *
-* data = adresse non utilisée ici. *
-* *
-* Description : Surveille les ajouts dans la partie principale. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void on_docking_to_main_panel(GtkDockStation *station, GtkWidget *widget, gpointer data)
-{
-
-
-
-
- g_panel_item_undock(_welcome);
-
-
-
- g_signal_handlers_disconnect_by_func(station,
- G_CALLBACK(on_docking_to_main_panel), NULL);
-
-
-}
-
diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c
deleted file mode 100644
index fa55fd7..0000000
--- a/src/gui/panels/welcome.c
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * welcome.c - panneau d'affichage d'accueil
- *
- * Copyright (C) 2012-2014 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * OpenIDA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * OpenIDA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "welcome.h"
-
-
-#include <string.h>
-#include <gtk/gtk.h>
-
-
-#include "panel-int.h"
-#include "../../gtkext/easygtk.h"
-#include "../../gtkext/support.h"
-
-
-
-/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */
-
-
-/* Panneau d'accueil (instance) */
-struct _GWelcomePanel
-{
- GPanelItem parent; /* A laisser en premier */
-
-};
-
-
-/* Panneau d'accueil (classe) */
-struct _GWelcomePanelClass
-{
- GPanelItemClass parent; /* A laisser en premier */
-
-};
-
-
-/* Initialise la classe des panneaux d'accueil. */
-static void g_welcome_panel_class_init(GWelcomePanelClass *);
-
-/* Initialise une instance de panneau d'accueil. */
-static void g_welcome_panel_init(GWelcomePanel *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* PARTIE PRINCIPALE DU PANNEAU */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type définit pour un panneau d'accueil. */
-G_DEFINE_TYPE(GWelcomePanel, g_welcome_panel, G_TYPE_PANEL_ITEM);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des panneaux d'accueil. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_welcome_panel_class_init(GWelcomePanelClass *klass)
-{
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : panel = instance à initialiser. *
-* *
-* Description : Initialise une instance de panneau d'accueil. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_welcome_panel_init(GWelcomePanel *panel)
-{
- GtkWidget *align; /* Alignement centré */
- gchar *filename; /* Chemin d'accès au fichier */
- GtkWidget *image; /* Image chargée */
- GEditorItem *base; /* Version basique d'instance */
-
- align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
- gtk_widget_show(align);
-
- filename = find_pixmap_file("welcome.png");
- image = qck_create_image(NULL, NULL, filename);
- gtk_container_add(GTK_CONTAINER(align), image);
-
- base = G_EDITOR_ITEM(panel);
- base->widget = align;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : ref = espace de référencement global. *
-* *
-* Description : Crée un panneau d'accueil. *
-* *
-* Retour : Adresse de la structure mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GEditorItem *g_welcome_panel_new(GObject *ref)
-{
- GEditorItem *result; /* Structure à retourner */
-
- result = g_object_new(G_TYPE_WELCOME_PANEL, NULL);
-
- g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_WELCOME_ID,
- _("Welcome"), G_EDITOR_ITEM(result)->widget, "M");
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : ref = espace de référencement global. *
-* *
-* Description : Construit et intègre un panneau d'accueil. *
-* *
-* Retour : Adresse du panneau mis en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GPanelItem *create_welcome_panel(GObject *ref)
-{
- GEditorItem *result; /* Elément réactif à renvoyer */
-
- result = g_welcome_panel_new(ref);
-
- /* Enregistre correctement le tout */
- register_editor_item(result);
-
- return G_PANEL_ITEM(result);
-
-}
diff --git a/src/gui/panels/welcome.h b/src/gui/panels/welcome.h
deleted file mode 100644
index 88c17bd..0000000
--- a/src/gui/panels/welcome.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * welcome.h - prototypes pour le panneau d'affichage d'accueil
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * OpenIDA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * OpenIDA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#ifndef _GUI_PANELS_WELCOME_H
-#define _GUI_PANELS_WELCOME_H
-
-
-#include <i18n.h>
-
-
-#include "panel.h"
-
-
-
-#define PANEL_WELCOME_ID _("Welcome")
-
-
-#define G_TYPE_WELCOME_PANEL g_welcome_panel_get_type()
-#define G_WELCOME_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_welcome_panel_get_type(), GWelcomePanel))
-#define G_IS_WELCOME_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_welcome_panel_get_type()))
-#define G_WELCOME_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_WELCOME_PANEL, GWelcomePanelClass))
-#define G_IS_WELCOME_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_WELCOME_PANEL))
-#define G_WELCOME_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_WELCOME_PANEL, GWelcomePanelClass))
-
-
-/* Panneau d'accueil (instance) */
-typedef struct _GWelcomePanel GWelcomePanel;
-
-/* Panneau d'accueil (classe) */
-typedef struct _GWelcomePanelClass GWelcomePanelClass;
-
-
-/* Indique le type définit pour un panneau d'accueil. */
-GType g_welcome_panel_get_type(void);
-
-/* Crée un panneau d'accueil. */
-GEditorItem *g_welcome_panel_new(GObject *);
-
-/* Construit et intègre un panneau d'accueil. */
-GPanelItem *create_welcome_panel(GObject *);
-
-
-
-#endif /* _GUI_PANELS_WELCOME_H */