Initial import of DeforaOS Notes

This is forked from DeforaOS Todo.
This commit is contained in:
Pierre Pronchery 2015-08-31 03:24:19 +02:00
commit e54e881eee
24 changed files with 2511 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
Makefile
/config.h
/config.sh
*~
*.a
*.dll
*.dylib
*.o
*.so
*.so.*

25
COPYING Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2009-2015, Pierre Pronchery <khorben@defora.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,10 @@
[Desktop Entry]
Name=DeforaOS Notes
GenericName=Notes
Comment=Keep a list of notes
TryExec=notes
Exec=notes
#Icon=
Type=Application
Categories=Office;GTK;
StartupNotify=true

4
data/project.conf Normal file
View File

@ -0,0 +1,4 @@
dist=Makefile,deforaos-notes.desktop
[deforaos-notes.desktop]
install=$(PREFIX)/share/applications

2
po/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/Notes.pot
/*.mo

4
po/POTFILES Normal file
View File

@ -0,0 +1,4 @@
../src/main.c
../src/noteedit.c
../src/notes.c
../src/window.c

122
po/es.po Normal file
View File

@ -0,0 +1,122 @@
# $Id$
# Copyright (c) 2015 Pierre Pronchery <khorben@defora.org>
# This file is distributed under the same license as the Notes package.
#
msgid ""
msgstr ""
"Project-Id-Version: Notes 0.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-08-31 03:17+0200\n"
"PO-Revision-Date: 2015-04-21 00:54+0200\n"
"Last-Translator: Ana Carolina Rocha <carolina@defora.org>\n"
"Language-Team: Spanish\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../src/main.c:90
#, c-format
msgid "Usage: %s\n"
msgstr "Usage: %s\n"
#: ../src/noteedit.c:76
msgid "Edit note: "
msgstr "Editar nota: "
#: ../src/noteedit.c:86
msgid "Title:"
msgstr "Título:"
#: ../src/noteedit.c:95
msgid "Description:"
msgstr "Descripción:"
#: ../src/notes.c:113
msgid "Title"
msgstr "Título"
#: ../src/notes.c:128 ../src/notes.c:363
msgid "New note"
msgstr "Nueva nota"
#: ../src/notes.c:129
msgid "Edit note"
msgstr "Editar nota"
#: ../src/notes.c:133 ../src/notes.c:136
msgid "Select all"
msgstr "Seleccionar todo"
#: ../src/notes.c:139
msgid "Delete note"
msgstr "Eliminar nota"
#: ../src/notes.c:143
msgid "Preferences"
msgstr "Preferencias"
#: ../src/notes.c:281
msgid "Notes for the DeforaOS desktop"
msgstr "Administrador de notas para el escritorio de DeforaOS"
#: ../src/notes.c:287
msgid "translator-credits"
msgstr "Ana Carolina Rocha <carolina@defora.org>"
#: ../src/notes.c:317 ../src/notes.c:322
msgid "Error"
msgstr "Error"
#: ../src/notes.c:392
msgid "Are you sure you want to delete the selected note(s)?"
msgstr "Está seguro que desea eliminar la(s) nota(s) seleccionada(s)?"
#: ../src/notes.c:597 ../src/notes.c:602
msgid "Question"
msgstr "Pregunta"
#: ../src/window.c:102
msgid "_New"
msgstr "_Nuevo"
#: ../src/window.c:104 ../src/window.c:143
msgid "_Edit"
msgstr "_Editar"
#: ../src/window.c:107
msgid "_Close"
msgstr "_Cerrar"
#: ../src/window.c:113
msgid "Select _All"
msgstr "Seleccionar _todo"
#: ../src/window.c:121
msgid "_Delete"
msgstr "_Eliminar tarea"
#: ../src/window.c:124
msgid "_Preferences"
msgstr "_Preferencias"
#: ../src/window.c:130
msgid "_Contents"
msgstr "_Contenidos"
#: ../src/window.c:132
msgid "_About"
msgstr "Acerca _de"
#: ../src/window.c:142
msgid "_File"
msgstr "_Archivo"
#: ../src/window.c:144
msgid "_Help"
msgstr "_Ayuda"
#: ../src/window.c:179
msgid "Notes"
msgstr "Notas"

122
po/fr.po Normal file
View File

@ -0,0 +1,122 @@
# $Id$
# Copyright (c) 2015 Pierre Pronchery <khorben@defora.org>
# This file is distributed under the same license as the Notes package.
#
msgid ""
msgstr ""
"Project-Id-Version: Notes 0.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-08-31 03:17+0200\n"
"PO-Revision-Date: 2010-04-23 14:35+0200\n"
"Last-Translator: Pierre Pronchery <khorben@defora.org>\n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: ../src/main.c:90
#, c-format
msgid "Usage: %s\n"
msgstr "Usage: %s\n"
#: ../src/noteedit.c:76
msgid "Edit note: "
msgstr "Modifier la note : "
#: ../src/noteedit.c:86
msgid "Title:"
msgstr "Titre:"
#: ../src/noteedit.c:95
msgid "Description:"
msgstr "Description:"
#: ../src/notes.c:113
msgid "Title"
msgstr "Titre"
#: ../src/notes.c:128 ../src/notes.c:363
msgid "New note"
msgstr "Nouvelle note"
#: ../src/notes.c:129
msgid "Edit note"
msgstr "Modifier la note"
#: ../src/notes.c:133 ../src/notes.c:136
msgid "Select all"
msgstr "Sélectionner tout"
#: ../src/notes.c:139
msgid "Delete note"
msgstr "Supprimer la note"
#: ../src/notes.c:143
msgid "Preferences"
msgstr "Préférences"
#: ../src/notes.c:281
msgid "Notes for the DeforaOS desktop"
msgstr "Gestionnaire de notes pour l'environnement DeforaOS"
#: ../src/notes.c:287
msgid "translator-credits"
msgstr "Pierre Pronchery <khorben@defora.org>"
#: ../src/notes.c:317 ../src/notes.c:322
msgid "Error"
msgstr "Erreur"
#: ../src/notes.c:392
msgid "Are you sure you want to delete the selected note(s)?"
msgstr "Voulez-vous vraiment supprimer la sélection?"
#: ../src/notes.c:597 ../src/notes.c:602
msgid "Question"
msgstr "Question"
#: ../src/window.c:102
msgid "_New"
msgstr "_Nouvelle tâche"
#: ../src/window.c:104 ../src/window.c:143
msgid "_Edit"
msgstr "É_dition"
#: ../src/window.c:107
msgid "_Close"
msgstr "_Fermer"
#: ../src/window.c:113
msgid "Select _All"
msgstr "Sélectionner _tout"
#: ../src/window.c:121
msgid "_Delete"
msgstr "_Supprimer"
#: ../src/window.c:124
msgid "_Preferences"
msgstr "_Préférences"
#: ../src/window.c:130
msgid "_Contents"
msgstr "_Sommaire"
#: ../src/window.c:132
msgid "_About"
msgstr "À _propos"
#: ../src/window.c:142
msgid "_File"
msgstr "_Fichier"
#: ../src/window.c:144
msgid "_Help"
msgstr "_Aide"
#: ../src/window.c:179
msgid "Notes"
msgstr "Notes"

210
po/gettext.sh Executable file
View File

@ -0,0 +1,210 @@
#!/bin/sh
#$Id$
#Copyright (c) 2010-2015 Pierre Pronchery <khorben@defora.org>
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#variables
PREFIX="/usr/local"
[ -f "../config.sh" ] && . "../config.sh"
LOCALEDIR="$PREFIX/share/locale"
POTFILES="POTFILES"
PROGNAME="gettext.sh"
#executables
DEBUG="_debug"
INSTALL="install -m 0644"
MKDIR="mkdir -p"
MSGFMT="msgfmt"
MSGINIT="msginit"
MSGMERGE="msgmerge"
RM="rm -f"
XGETTEXT="xgettext --force-po"
#functions
#debug
_debug()
{
echo "$@" 1>&2
"$@"
}
#error
_error()
{
echo "$PROGNAME: $@" 1>&2
return 2
}
#usage
_usage()
{
echo "Usage: $PROGNAME [-c|-i|-u][-P prefix] target..." 1>&2
return 1
}
#gettext_mo
_gettext_mo()
{
package="$1"
lang="$2"
potfile="$3"
pofile="$4"
mofile="$5"
_gettext_po "$package" "$lang" "$potfile" "$pofile" || return 1
$DEBUG $MSGFMT -c -v -o "$mofile" "$pofile" || return 1
}
#gettext_po
_gettext_po()
{
package="$1"
lang="$2"
potfile="$3"
pofile="$4"
if [ -f "$pofile" ]; then
$DEBUG $MSGMERGE -U "$pofile" "$potfile" || return 1
else
$DEBUG $MSGINIT -l "$lang" -o "$pofile" -i "$potfile" \
|| return 1
fi
}
#gettext_pot
_gettext_pot()
{
package="$1"
potfile="$2"
$DEBUG $XGETTEXT -d "$package" -o "$potfile" --keyword="_" \
--keyword="N_" -f "$POTFILES" || return 1
}
#main
clean=0
install=0
uninstall=0
while getopts "ciuP:" name; do
case "$name" in
c)
clean=1
;;
i)
uninstall=0
install=1
;;
u)
install=0
uninstall=1
;;
P)
PREFIX="$OPTARG"
;;
?)
_usage
exit $?
;;
esac
done
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
_usage
exit $?
fi
#check the variables
if [ -z "$PACKAGE" ]; then
_error "The PACKAGE variable needs to be set"
exit $?
fi
LOCALEDIR="$PREFIX/share/locale"
while [ $# -gt 0 ]; do
target="$1"
source="${target#$OBJDIR}"
lang="${source%%.mo}"
lang="${lang%%.po}"
shift
#clean
[ "$clean" -ne 0 ] && continue
#uninstall
if [ "$uninstall" -eq 1 ]; then
$DEBUG $RM "$LOCALEDIR/$lang/LC_MESSAGES/$PACKAGE.mo" \
|| exit 2
continue
fi
#install
if [ "$install" -eq 1 ]; then
$DEBUG $MKDIR "$LOCALEDIR/$lang/LC_MESSAGES" || exit 2
$DEBUG $INSTALL "$target" \
"$LOCALEDIR/$lang/LC_MESSAGES/$PACKAGE.mo" \
|| exit 2
continue
fi
#create
case "$target" in
*.mo)
#XXX may not match
if [ -n "$OBJDIR" ]; then
potfile="$OBJDIR/$PACKAGE.pot"
else
potfile="$PACKAGE.pot"
fi
mofile="$target"
pofile="${source%%.mo}.po"
_gettext_mo "$PACKAGE" "$lang" "$potfile" "$pofile" \
"$mofile" || exit 2
;;
*.po)
#XXX may not match
if [ -n "$OBJDIR" ]; then
potfile="$OBJDIR/$PACKAGE.pot"
else
potfile="$PACKAGE.pot"
fi
pofile="$target"
_gettext_po "$PACKAGE" "$lang" "$potfile" "$pofile" \
|| exit 2
;;
*.pot)
package="${source%%.pot}"
potfile="$target"
_gettext_pot "$package" "$potfile" || exit 2
;;
*)
exit 2
;;
esac
done

19
po/project.conf Normal file
View File

@ -0,0 +1,19 @@
targets=Notes.pot,es.mo,fr.mo
dist=Makefile,gettext.sh,POTFILES,es.po,fr.po
[Notes.pot]
type=script
script=./gettext.sh
depends=POTFILES
[es.mo]
type=script
script=./gettext.sh
install=
depends=$(OBJDIR)Notes.pot,es.po
[fr.mo]
type=script
script=./gettext.sh
install=
depends=$(OBJDIR)Notes.pot,fr.po

6
project.conf Normal file
View File

@ -0,0 +1,6 @@
package=Notes
version=0.0.0
config=h,sh
subdirs=data,po,src,tools
dist=Makefile,COPYING,config.h,config.sh

1
src/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/notes

116
src/main.c Normal file
View File

@ -0,0 +1,116 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <unistd.h>
#include <stdio.h>
#include <locale.h>
#include <libintl.h>
#include <gtk/gtk.h>
#include <System.h>
#include "window.h"
#include "../config.h"
#define _(string) gettext(string)
/* constants */
#ifndef PROGNAME
# define PROGNAME "notes"
#endif
#ifndef PREFIX
# define PREFIX "/usr/local"
#endif
#ifndef DATADIR
# define DATADIR PREFIX "/share"
#endif
#ifndef LOCALEDIR
# define LOCALEDIR DATADIR "/locale"
#endif
/* private */
/* prototypes */
static int _notes(void);
static int _error(char const * message, int ret);
static int _usage(void);
/* functions */
/* notes */
static int _notes(void)
{
NotesWindow * notes;
if((notes = noteswindow_new()) == NULL)
return error_print(PACKAGE);
gtk_main();
noteswindow_delete(notes);
return 0;
}
/* error */
static int _error(char const * message, int ret)
{
fputs(PROGNAME ": ", stderr);
perror(message);
return ret;
}
/* usage */
static int _usage(void)
{
fprintf(stderr, _("Usage: %s\n"), PROGNAME);
return 1;
}
/* public */
/* functions */
/* main */
int main(int argc, char * argv[])
{
int o;
if(setlocale(LC_ALL, "") == NULL)
_error("setlocale", 1);
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
gtk_init(&argc, &argv);
while((o = getopt(argc, argv, "")) != -1)
switch(o)
{
default:
return _usage();
}
if(optind != argc)
return _usage();
return (_notes() == 0) ? 0 : 2;
}

202
src/note.c Normal file
View File

@ -0,0 +1,202 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <System.h>
#include "note.h"
/* Note */
/* private */
/* types */
struct _Note
{
Config * config;
/* internal */
char * filename;
String * description;
};
/* public */
/* functions */
/* note_new */
Note * note_new(void)
{
Note * note;
if((note = object_new(sizeof(*note))) == NULL)
return NULL;
note->config = config_new();
note->filename = NULL;
note->description = NULL;
if(note->config == NULL)
{
note_delete(note);
return NULL;
}
return note;
}
/* note_new_from_file */
Note * note_new_from_file(char const * filename)
{
Note * note;
if((note = note_new()) == NULL)
return NULL;
if(note_set_filename(note, filename) != 0
|| note_load(note) != 0)
{
note_delete(note);
return NULL;
}
return note;
}
/* note_delete */
void note_delete(Note * note)
{
string_delete(note->description);
free(note->filename);
if(note->config != NULL)
config_delete(note->config);
object_delete(note);
}
/* accessors */
/* note_get_description */
char const * note_get_description(Note * note)
{
String const * p;
String * q;
if(note->description != NULL)
return note->description;
if((p = config_get(note->config, NULL, "description")) == NULL)
return "";
if((q = string_new_replace(p, "\\n", "\n")) == NULL
|| string_replace(&q, "\\\\", "\\") != 0)
return NULL;
note->description = q;
return note->description;
}
/* note_get_filename */
char const * note_get_filename(Note * note)
{
return note->filename;
}
/* note_get_title */
char const * note_get_title(Note * note)
{
char const * ret;
if((ret = config_get(note->config, NULL, "title")) == NULL)
return "";
return ret;
}
/* note_set_description */
int note_set_description(Note * note, char const * description)
{
String * d;
if((d = string_new_replace(description, "\\", "\\\\")) == NULL)
return -1;
if(string_replace(&d, "\n", "\\n") != 0
|| config_set(note->config, NULL, "description", d)
!= 0)
{
string_delete(d);
return -1;
}
string_delete(note->description);
note->description = d;
return 0;
}
/* note_set_filename */
int note_set_filename(Note * note, char const * filename)
{
char * p;
if((p = strdup(filename)) == NULL)
return -1; /* XXX set error */
free(note->filename);
note->filename = p;
return 0;
}
/* note_set_title */
int note_set_title(Note * note, char const * title)
{
return config_set(note->config, NULL, "title", title);
}
/* useful */
/* note_load */
int note_load(Note * note)
{
config_reset(note->config);
return config_load(note->config, note->filename);
}
/* note_save */
int note_save(Note * note)
{
if(note->filename == NULL)
return -1; /* XXX set error */
return config_save(note->config, note->filename);
}
/* note_unlink */
int note_unlink(Note * note)
{
if(note->filename == NULL)
return -1; /* XXX set error */
return unlink(note->filename);
}

61
src/note.h Normal file
View File

@ -0,0 +1,61 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef NOTES_NOTE_H
# define NOTES_NOTE_H
/* Note */
/* types */
typedef struct _Note Note;
/* functions */
Note * note_new(void);
Note * note_new_from_file(char const * filename);
void note_delete(Note * note);
/* accessors */
char const * note_get_description(Note * note);
char const * note_get_filename(Note * note);
char const * note_get_title(Note * note);
int note_set_description(Note * note, char const * description);
int note_set_filename(Note * note, char const * filename);
int note_set_title(Note * note, char const * title);
/* useful */
int note_load(Note * note);
int note_save(Note * note);
int note_unlink(Note * note);
#endif /* !NOTES_NOTE_H */

163
src/noteedit.c Normal file
View File

@ -0,0 +1,163 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <stdlib.h>
#include <libintl.h>
#include <gtk/gtk.h>
#include "noteedit.h"
#define _(string) gettext(string)
/* NoteEdit */
/* private */
/* types */
struct _NoteEdit
{
Notes * notes;
Note * note;
/* widgets */
GtkWidget * window;
GtkWidget * title;
GtkWidget * description;
};
/* public */
/* functions */
/* note_new */
static void _on_noteedit_cancel(gpointer data);
static void _on_noteedit_ok(gpointer data);
NoteEdit * noteedit_new(Notes * notes, Note * note)
{
NoteEdit * noteedit;
char buf[80];
GtkSizeGroup * group;
GtkWidget * vbox;
GtkWidget * hbox;
GtkWidget * widget;
GtkWidget * bbox;
GtkWidget * scrolled;
char const * description;
if((noteedit = malloc(sizeof(*noteedit))) == NULL)
return NULL;
noteedit->notes = notes;
noteedit->note = note;
noteedit->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
snprintf(buf, sizeof(buf), "%s%s", _("Edit note: "), note_get_title(
note));
gtk_window_set_default_size(GTK_WINDOW(noteedit->window), 300, 400);
gtk_window_set_title(GTK_WINDOW(noteedit->window), buf);
g_signal_connect_swapped(noteedit->window, "delete-event", G_CALLBACK(
_on_noteedit_cancel), noteedit);
group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
vbox = gtk_vbox_new(FALSE, 4);
/* title */
hbox = gtk_hbox_new(FALSE, 4);
widget = gtk_label_new(_("Title:"));
gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
gtk_size_group_add_widget(group, widget);
gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
noteedit->title = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(noteedit->title), note_get_title(note));
gtk_box_pack_start(GTK_BOX(hbox), noteedit->title, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
/* description */
widget = gtk_label_new(_("Description:"));
gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
gtk_size_group_add_widget(group, widget);
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled),
GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
noteedit->description = gtk_text_view_new();
if((description = note_get_description(note)) != NULL)
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(
noteedit->description)),
description, -1);
gtk_container_add(GTK_CONTAINER(scrolled), noteedit->description);
gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
gtk_box_set_spacing(GTK_BOX(bbox), 4);
widget = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
g_signal_connect_swapped(widget, "clicked", G_CALLBACK(
_on_noteedit_cancel), noteedit);
gtk_container_add(GTK_CONTAINER(bbox), widget);
widget = gtk_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect_swapped(widget, "clicked", G_CALLBACK(_on_noteedit_ok),
noteedit);
gtk_container_add(GTK_CONTAINER(bbox), widget);
gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(noteedit->window), 4);
gtk_container_add(GTK_CONTAINER(noteedit->window), vbox);
gtk_widget_show_all(noteedit->window);
return noteedit;
}
static void _on_noteedit_cancel(gpointer data)
{
NoteEdit * noteedit = data;
noteedit_delete(noteedit);
}
static void _on_noteedit_ok(gpointer data)
{
NoteEdit * noteedit = data;
GtkTextBuffer * tbuf;
GtkTextIter start;
GtkTextIter end;
gchar * description;
note_set_title(noteedit->note, gtk_entry_get_text(GTK_ENTRY(
noteedit->title)));
tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(noteedit->description));
gtk_text_buffer_get_start_iter(tbuf, &start);
gtk_text_buffer_get_end_iter(tbuf, &end);
description = gtk_text_buffer_get_text(tbuf, &start, &end, FALSE);
note_set_description(noteedit->note, description);
g_free(description);
note_save(noteedit->note);
notes_note_reload_all(noteedit->notes); /* XXX violent solution */
_on_noteedit_cancel(noteedit);
}
/* noteedit_delete */
void noteedit_delete(NoteEdit * noteedit)
{
gtk_widget_destroy(noteedit->window);
free(noteedit);
}

47
src/noteedit.h Normal file
View File

@ -0,0 +1,47 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef NOTES_NOTEEDIT_H
# define NOTES_NOTEEDIT_H
# include "note.h"
# include "notes.h"
/* NoteEdit */
/* types */
typedef struct _NoteEdit NoteEdit;
/* functions */
NoteEdit * noteedit_new(Notes * notes, Note * note);
void noteedit_delete(NoteEdit * noteedit);
#endif /* !NOTES_NOTEEDIT_H */

783
src/notes.c Normal file
View File

@ -0,0 +1,783 @@
/* $Id$ */
static char _copyright[] =
"Copyright © 2015 Pierre Pronchery <khorben@defora.org>";
/* This file is part of DeforaOS Desktop Notes */
static char const _license[] = "All rights reserved.\n"
"\n"
"Redistribution and use in source and binary forms, with or without\n"
"modification, are permitted provided that the following conditions are\n"
"met:\n"
"\n"
"1. Redistributions of source code must retain the above copyright\n"
" notice, this list of conditions and the following disclaimer.\n"
"\n"
"2. Redistributions in binary form must reproduce the above copyright\n"
" notice, this list of conditions and the following disclaimer in the\n"
" documentation and/or other materials provided with the distribution.\n"
"\n"
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n"
"IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n"
"TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n"
"PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
"HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n"
"TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n"
"PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n"
"LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
/* TODO:
* - add a clear/apply button (allocate a temporary object) */
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <libintl.h>
#include <gtk/gtk.h>
#include <System.h>
#include <Desktop.h>
#include "noteedit.h"
#include "notes.h"
#include "../config.h"
#define _(string) gettext(string)
#define N_(string) (string)
/* Notes */
/* private */
/* types */
typedef enum _NotesColumn
{
ND_COL_NOTE, ND_COL_TITLE, ND_COL_CATEGORY
} NotesColumn;
#define ND_COL_LAST ND_COL_CATEGORY
#define ND_COL_COUNT (ND_COL_LAST + 1)
struct _Notes
{
GtkWidget * window;
GtkWidget * widget;
GtkWidget * scrolled;
GtkListStore * store;
GtkListStore * priorities;
GtkTreeModel * filter;
GtkTreeModel * filter_sort;
GtkWidget * view;
GtkTreeViewColumn * columns[ND_COL_COUNT];
GtkWidget * about;
};
/* prototypes */
static int _notes_confirm(GtkWidget * window, char const * message);
static gboolean _notes_get_iter(Notes * notes, GtkTreeIter * iter,
GtkTreePath * path);
static char * _notes_note_get_directory(void);
static char * _notes_note_get_filename(char const * filename);
static char * _notes_note_get_new_filename(void);
static void _notes_note_save(Notes * notes, GtkTreeIter * iter);
/* callbacks */
/* toolbar */
static void _notes_on_new(gpointer data);
static void _notes_on_edit(gpointer data);
static void _notes_on_select_all(gpointer data);
static void _notes_on_delete(gpointer data);
#ifdef EMBEDDED
static void _notes_on_preferences(gpointer data);
#endif
/* view */
static void _notes_on_note_activated(gpointer data);
static void _notes_on_note_cursor_changed(gpointer data);
static void _notes_on_note_title_edited(GtkCellRendererText * renderer,
gchar * path, gchar * title, gpointer data);
/* constants */
static const struct
{
int col;
char const * title;
int sort;
GCallback callback;
} _notes_columns[] =
{
{ ND_COL_TITLE, N_("Title"), ND_COL_TITLE, G_CALLBACK(
_notes_on_note_title_edited) },
{ 0, NULL, 0, NULL }
};
static char const * _authors[] =
{
"Pierre Pronchery <khorben@defora.org>",
NULL
};
/* toolbar */
static DesktopToolbar _toolbar[] =
{
{ N_("New note"), G_CALLBACK(_notes_on_new), GTK_STOCK_NEW, 0, 0, NULL },
{ N_("Edit note"), G_CALLBACK(_notes_on_edit), GTK_STOCK_EDIT, 0, 0,
NULL },
{ "", NULL, NULL, 0, 0, NULL },
#if GTK_CHECK_VERSION(2, 10, 0)
{ N_("Select all"), G_CALLBACK(_notes_on_select_all),
GTK_STOCK_SELECT_ALL, 0, 0, NULL },
#else
{ N_("Select all"), G_CALLBACK(_notes_on_select_all), "edit-select-all",
0, 0, NULL },
#endif
{ N_("Delete note"), G_CALLBACK(_notes_on_delete), GTK_STOCK_DELETE, 0,
0, NULL },
#ifdef EMBEDDED
{ "", NULL, NULL, 0, 0, NULL },
{ N_("Preferences"), G_CALLBACK(_notes_on_preferences),
GTK_STOCK_PREFERENCES, 0, 0, NULL },
#endif
{ "", NULL, NULL, 0, 0, NULL },
{ NULL, NULL, NULL, 0, 0, NULL }
};
/* public */
/* functions */
/* notes_new */
static void _new_view(Notes * notes);
static gboolean _new_idle(gpointer data);
Notes * notes_new(GtkWidget * window, GtkAccelGroup * group)
{
Notes * notes;
GtkWidget * vbox;
GtkWidget * widget;
if((notes = object_new(sizeof(*notes))) == NULL)
return NULL;
/* main window */
notes->window = window;
vbox = gtk_vbox_new(FALSE, 0);
notes->widget = vbox;
/* toolbar */
widget = desktop_toolbar_create(_toolbar, notes, group);
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
/* view */
notes->scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(notes->scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
_new_view(notes);
gtk_box_pack_start(GTK_BOX(vbox), notes->scrolled, TRUE, TRUE, 0);
notes->about = NULL;
g_idle_add(_new_idle, notes);
return notes;
}
static void _new_view(Notes * notes)
{
size_t i;
GtkTreeSelection * sel;
GtkCellRenderer * renderer;
GtkTreeViewColumn * column;
notes->store = gtk_list_store_new(ND_COL_COUNT,
G_TYPE_POINTER, /* note */
G_TYPE_STRING, /* title */
G_TYPE_STRING); /* category */
/* XXX get rid of filter? */
notes->filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(notes->store),
NULL);
notes->filter_sort = gtk_tree_model_sort_new_with_model(notes->filter);
notes->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(
notes->filter_sort));
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(notes->view), TRUE);
if((sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(notes->view)))
!= NULL)
gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
g_signal_connect_swapped(notes->view, "cursor-changed", G_CALLBACK(
_notes_on_note_cursor_changed), notes);
g_signal_connect_swapped(notes->view, "row-activated", G_CALLBACK(
_notes_on_note_activated), notes);
/* columns */
memset(&notes->columns, 0, sizeof(notes->columns));
for(i = 0; _notes_columns[i].title != NULL; i++)
{
renderer = gtk_cell_renderer_text_new();
if(_notes_columns[i].callback != NULL)
{
g_object_set(G_OBJECT(renderer), "editable", TRUE,
"ellipsize", PANGO_ELLIPSIZE_END, NULL);
g_signal_connect(renderer, "edited", G_CALLBACK(
_notes_columns[i].callback),
notes);
}
column = gtk_tree_view_column_new_with_attributes(
_(_notes_columns[i].title), renderer, "text",
_notes_columns[i].col, NULL);
notes->columns[_notes_columns[i].col] = column;
#if GTK_CHECK_VERSION(2, 4, 0)
gtk_tree_view_column_set_expand(column, TRUE);
#endif
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sort_column_id(column,
_notes_columns[i].sort);
gtk_tree_view_append_column(GTK_TREE_VIEW(notes->view), column);
}
gtk_tree_view_column_set_sort_column_id(column, ND_COL_TITLE);
gtk_container_add(GTK_CONTAINER(notes->scrolled), notes->view);
gtk_tree_view_append_column(GTK_TREE_VIEW(notes->view), column);
}
static gboolean _new_idle(gpointer data)
{
Notes * notes = data;
notes_note_reload_all(notes);
return FALSE;
}
/* notes_delete */
void notes_delete(Notes * notes)
{
notes_note_save_all(notes);
notes_note_remove_all(notes);
free(notes);
object_delete(notes);
}
/* accessors */
/* notes_get_widget */
GtkWidget * notes_get_widget(Notes * notes)
{
return notes->widget;
}
/* useful */
/* notes_about */
static gboolean _about_on_closex(gpointer data);
void notes_about(Notes * notes)
{
if(notes->about != NULL)
{
gtk_widget_show(notes->about);
return;
}
notes->about = desktop_about_dialog_new();
gtk_window_set_transient_for(GTK_WINDOW(notes->about),
GTK_WINDOW(notes->window));
desktop_about_dialog_set_authors(notes->about, _authors);
desktop_about_dialog_set_comments(notes->about,
_("Notes for the DeforaOS desktop"));
desktop_about_dialog_set_copyright(notes->about, _copyright);
desktop_about_dialog_set_logo_icon_name(notes->about, "notes");
desktop_about_dialog_set_license(notes->about, _license);
desktop_about_dialog_set_program_name(notes->about, PACKAGE);
desktop_about_dialog_set_translator_credits(notes->about,
_("translator-credits"));
desktop_about_dialog_set_version(notes->about, VERSION);
desktop_about_dialog_set_website(notes->about, "http://www.defora.org/");
g_signal_connect_swapped(notes->about, "delete-event", G_CALLBACK(
_about_on_closex), notes);
gtk_widget_show(notes->about);
}
static gboolean _about_on_closex(gpointer data)
{
Notes * notes = data;
gtk_widget_hide(notes->about);
return TRUE;
}
/* notes_error */
static int _error_text(char const * message, int ret);
int notes_error(Notes * notes, char const * message, int ret)
{
GtkWidget * dialog;
if(notes == NULL)
return _error_text(message, ret);
dialog = gtk_message_dialog_new(GTK_WINDOW(notes->window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s",
#if GTK_CHECK_VERSION(2, 8, 0)
_("Error"));
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
"%s",
#endif
message);
gtk_window_set_title(GTK_WINDOW(dialog), _("Error"));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
return ret;
}
static int _error_text(char const * message, int ret)
{
fputs(PACKAGE ": ", stderr);
fputs(message, stderr);
fputc('\n', stderr);
return ret;
}
/* notes_show_preferences */
void notes_show_preferences(Notes * notes, gboolean show)
{
/* FIXME implement */
}
/* notes */
/* notes_note_add */
Note * notes_note_add(Notes * notes, Note * note)
{
GtkTreeIter iter;
char * filename;
if(note == NULL)
{
if((note = note_new()) == NULL)
return NULL;
if((filename = _notes_note_get_new_filename()) == NULL)
{
notes_error(notes, error_get(), 0);
note_delete(note);
return NULL;
}
note_set_filename(note, filename);
free(filename);
note_set_title(note, _("New note"));
note_save(note);
}
gtk_list_store_insert(notes->store, &iter, 0);
gtk_list_store_set(notes->store, &iter, ND_COL_NOTE, note,
ND_COL_TITLE, note_get_title(note), -1);
return note;
}
/* notes_note_delete_selected */
static void _note_delete_selected_foreach(GtkTreeRowReference * reference,
Notes * notes);
void notes_note_delete_selected(Notes * notes)
{
GtkTreeSelection * treesel;
GList * selected;
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GtkTreeRowReference * reference;
GList * s;
GtkTreePath * path;
if((treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(notes->view)))
== NULL)
return;
if((selected = gtk_tree_selection_get_selected_rows(treesel, NULL))
== NULL)
return;
if(_notes_confirm(notes->window, _("Are you sure you want to delete the"
" selected note(s)?")) != 0)
return;
for(s = g_list_first(selected); s != NULL; s = g_list_next(s))
{
if((path = s->data) == NULL)
continue;
reference = gtk_tree_row_reference_new(model, path);
s->data = reference;
gtk_tree_path_free(path);
}
g_list_foreach(selected, (GFunc)_note_delete_selected_foreach, notes);
g_list_free(selected);
}
static void _note_delete_selected_foreach(GtkTreeRowReference * reference,
Notes * notes)
{
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GtkTreePath * path;
GtkTreeIter iter;
Note * note;
if(reference == NULL)
return;
if((path = gtk_tree_row_reference_get_path(reference)) == NULL)
return;
if(_notes_get_iter(notes, &iter, path) == TRUE)
{
gtk_tree_model_get(model, &iter, ND_COL_NOTE, &note, -1);
note_unlink(note);
note_delete(note);
}
gtk_list_store_remove(notes->store, &iter);
gtk_tree_path_free(path);
}
/* notes_note_cursor_changed */
void notes_note_cursor_changed(Notes * notes)
{
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GtkTreePath * path = NULL;
GtkTreeViewColumn * column = NULL;
GtkTreeIter iter;
Note * note = NULL;
gint id = -1;
gtk_tree_view_get_cursor(GTK_TREE_VIEW(notes->view), &path, &column);
if(path == NULL)
return;
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_model_get(model, &iter, ND_COL_NOTE, &note, -1);
if(column != NULL)
id = gtk_tree_view_column_get_sort_column_id(column);
gtk_tree_path_free(path);
}
/* notes_note_edit */
void notes_note_edit(Notes * notes)
{
GtkTreeSelection * treesel;
GList * selected;
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GList * s;
GtkTreePath * path;
GtkTreeIter iter;
Note * note;
if((treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(notes->view)))
== NULL)
return;
if((selected = gtk_tree_selection_get_selected_rows(treesel, NULL))
== NULL)
return;
for(s = g_list_first(selected); s != NULL; s = g_list_next(s))
{
if((path = s->data) == NULL)
continue;
if(_notes_get_iter(notes, &iter, path) != TRUE)
continue;
gtk_tree_model_get(model, &iter, ND_COL_NOTE, &note, -1);
if(note != NULL)
noteedit_new(notes, note);
}
g_list_free(selected);
}
/* notes_note_reload_all */
int notes_note_reload_all(Notes * notes)
{
int ret = 0;
char * filename;
DIR * dir;
struct dirent * de;
Note * note;
if((filename = _notes_note_get_directory()) == NULL)
return notes_error(notes, error_get(), 1);
if((dir = opendir(filename)) == NULL)
{
if(errno != ENOENT)
{
error_set("%s: %s", filename, strerror(errno));
ret = notes_error(notes, error_get(), 1);
}
}
else
{
notes_note_remove_all(notes);
while((de = readdir(dir)) != NULL)
{
if(strncmp(de->d_name, "note.", 5) != 0)
continue;
free(filename);
if((filename = _notes_note_get_filename(de->d_name))
== NULL)
continue; /* XXX report error */
if((note = note_new_from_file(filename)) == NULL)
{
notes_error(NULL, error_get(), 1);
continue;
}
if(notes_note_add(notes, note) == NULL)
{
note_delete(note);
continue; /* XXX report error */
}
}
}
free(filename);
return ret;
}
/* notes_note_remove_all */
void notes_note_remove_all(Notes * notes)
{
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GtkTreeIter iter;
gboolean valid;
Note * note;
valid = gtk_tree_model_get_iter_first(model, &iter);
for(; valid == TRUE; valid = gtk_tree_model_iter_next(model, &iter))
{
gtk_tree_model_get(model, &iter, ND_COL_NOTE, &note, -1);
note_delete(note);
}
gtk_list_store_clear(notes->store);
}
/* notes_note_save_all */
void notes_note_save_all(Notes * notes)
{
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GtkTreeIter iter;
gboolean valid;
valid = gtk_tree_model_get_iter_first(model, &iter);
for(; valid == TRUE; valid = gtk_tree_model_iter_next(model, &iter))
_notes_note_save(notes, &iter);
}
/* notes_note_select_all */
void notes_note_select_all(Notes * notes)
{
GtkTreeSelection * sel;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(notes->view));
gtk_tree_selection_select_all(sel);
}
/* notes_note_set_title */
void notes_note_set_title(Notes * notes, GtkTreePath * path, char const * title)
{
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
GtkTreeIter iter;
Note * note;
_notes_get_iter(notes, &iter, path);
gtk_tree_model_get(model, &iter, ND_COL_NOTE, &note, -1);
note_set_title(note, title);
gtk_list_store_set(notes->store, &iter, ND_COL_TITLE, title, -1);
note_save(note);
}
/* private */
/* functions */
/* notes_confirm */
static int _notes_confirm(GtkWidget * window, char const * message)
{
GtkWidget * dialog;
int res;
dialog = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s",
#if GTK_CHECK_VERSION(2, 8, 0)
_("Question"));
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
"%s",
#endif
message);
gtk_window_set_title(GTK_WINDOW(dialog), _("Question"));
res = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
if(res == GTK_RESPONSE_YES)
return 0;
return 1;
}
/* notes_get_iter */
static gboolean _notes_get_iter(Notes * notes, GtkTreeIter * iter,
GtkTreePath * path)
{
GtkTreeIter p;
if(gtk_tree_model_get_iter(GTK_TREE_MODEL(notes->filter_sort), iter,
path) == FALSE)
return FALSE;
gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(
notes->filter_sort), &p, iter);
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(
notes->filter), iter, &p);
return TRUE;
}
/* notes_note_get_directory */
static char * _notes_note_get_directory(void)
{
char const * homedir;
size_t len;
char const directory[] = ".notes";
char * filename;
if((homedir = getenv("HOME")) == NULL)
homedir = g_get_home_dir();
len = strlen(homedir) + 1 + sizeof(directory);
if((filename = malloc(len)) == NULL)
return NULL;
snprintf(filename, len, "%s/%s", homedir, directory);
return filename;
}
/* notes_note_get_filename */
static char * _notes_note_get_filename(char const * filenam)
{
char const * homedir;
int len;
char const directory[] = ".notes";
char * pathname;
if((homedir = getenv("HOME")) == NULL)
homedir = g_get_home_dir();
len = strlen(homedir) + 1 + sizeof(directory) + 1 + strlen(filenam) + 1;
if((pathname = malloc(len)) == NULL)
return NULL;
snprintf(pathname, len, "%s/%s/%s", homedir, directory, filenam);
return pathname;
}
/* notes_note_get_new_filename */
static char * _notes_note_get_new_filename(void)
{
char const * homedir;
int len;
char const directory[] = ".notes";
char template[] = "note.XXXXXX";
char * filename;
int fd;
if((homedir = getenv("HOME")) == NULL)
homedir = g_get_home_dir();
len = strlen(homedir) + 1 + sizeof(directory) + 1 + sizeof(template);
if((filename = malloc(len)) == NULL)
return NULL;
snprintf(filename, len, "%s/%s", homedir, directory);
if((mkdir(filename, 0777) != 0 && errno != EEXIST)
|| snprintf(filename, len, "%s/%s/%s", homedir,
directory, template) >= len
|| (fd = mkstemp(filename)) < 0)
{
error_set("%s: %s", filename, strerror(errno));
free(filename);
return NULL;
}
close(fd);
return filename;
}
/* notes_note_save */
static void _notes_note_save(Notes * notes, GtkTreeIter * iter)
{
GtkTreeModel * model = GTK_TREE_MODEL(notes->store);
Note * note;
gtk_tree_model_get(model, iter, ND_COL_NOTE, &note, -1);
note_save(note);
}
/* callbacks */
/* toolbar */
/* notes_on_delete */
static void _notes_on_delete(gpointer data)
{
Notes * notes = data;
notes_note_delete_selected(notes);
}
/* notes_on_edit */
static void _notes_on_edit(gpointer data)
{
Notes * notes = data;
notes_note_edit(notes);
}
/* notes_on_new */
static void _notes_on_new(gpointer data)
{
Notes * notes = data;
notes_note_add(notes, NULL);
}
#ifdef EMBEDDED
/* notes_on_preferences */
static void _notes_on_preferences(gpointer data)
{
Notes * notes = data;
notes_show_preferences(notes, TRUE);
}
#endif
/* notes_on_select_all */
static void _notes_on_select_all(gpointer data)
{
Notes * notes = data;
notes_note_select_all(notes);
}
/* view */
/* notes_on_note_activated */
static void _notes_on_note_activated(gpointer data)
{
Notes * notes = data;
notes_note_edit(notes);
}
/* notes_on_note_cursor_changed */
static void _notes_on_note_cursor_changed(gpointer data)
{
Notes * notes = data;
notes_note_cursor_changed(notes);
}
/* notes_on_note_title_edited */
static void _notes_on_note_title_edited(GtkCellRendererText * renderer,
gchar * path, gchar * title, gpointer data)
{
Notes * notes = data;
GtkTreePath * treepath;
treepath = gtk_tree_path_new_from_string(path);
notes_note_set_title(notes, treepath, title);
gtk_tree_path_free(treepath);
}

71
src/notes.h Normal file
View File

@ -0,0 +1,71 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef NOTES_NOTES_H
# define NOTES_NOTES_H
# include "note.h"
# include <gtk/gtk.h>
/* Notes */
/* types */
typedef struct _Notes Notes;
/* functions */
Notes * notes_new(GtkWidget * window, GtkAccelGroup * group);
void notes_delete(Notes * notes);
/* accessors */
GtkWidget * notes_get_widget(Notes * notes);
/* useful */
void notes_about(Notes * notes);
int notes_error(Notes * notes, char const * message, int ret);
void notes_show_preferences(Notes * notes, gboolean show);
/* notes */
Note * notes_note_add(Notes * notes, Note * note);
void notes_note_delete_selected(Notes * notes);
void notes_note_remove_all(Notes * notes);
/* accessors */
void notes_note_set_title(Notes * notes, GtkTreePath * path,
char const * title);
void notes_note_cursor_changed(Notes * notes);
void notes_note_edit(Notes * notes);
int notes_note_reload_all(Notes * notes);
void notes_note_save_all(Notes * notes);
void notes_note_select_all(Notes * notes);
#endif /* !NOTES_NOTES_H */

29
src/project.conf Normal file
View File

@ -0,0 +1,29 @@
targets=notes
#cppflags=-D EMBEDDED
cflags_force=`pkg-config --cflags libDesktop`
cflags=-W -Wall -g -O2 -pedantic -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector-all
ldflags_force=`pkg-config --libs libDesktop` -lintl
ldflags=-Wl,-pie
dist=Makefile,note.h,noteedit.h,notes.h,window.h
[notes]
type=binary
sources=note.c,noteedit.c,notes.c,window.c,main.c
install=$(BINDIR)
[main.c]
depends=note.h,notes.h,../config.h
[note.c]
depends=note.h
cflags=-fPIC
[noteedit.c]
cflags=-fPIC
[notes.c]
depends=note.h,notes.h,../config.h
cflags=-fPIC
[window.c]
depends=notes.h,window.h

321
src/window.c Normal file
View File

@ -0,0 +1,321 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <stdlib.h>
#include <libintl.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <Desktop.h>
#include "notes.h"
#include "window.h"
#include "../config.h"
#define _(string) gettext(string)
#define N_(string) (string)
#ifndef PROGNAME
# define PROGNAME "notes"
#endif
/* NotesWindow */
/* private */
/* types */
struct _NotesWindow
{
Notes * notes;
/* widgets */
GtkWidget * window;
GtkWidget * statusbar;
};
/* prototypes */
/* callbacks */
static void _noteswindow_on_close(gpointer data);
static gboolean _noteswindow_on_closex(gpointer data);
static void _noteswindow_on_edit(gpointer data);
static void _noteswindow_on_new(gpointer data);
static void _noteswindow_on_preferences(gpointer data);
#ifndef EMBEDDED
/* menus */
/* file menu */
static void _noteswindow_on_file_new(gpointer data);
static void _noteswindow_on_file_edit(gpointer data);
static void _noteswindow_on_file_close(gpointer data);
/* edit menu */
static void _noteswindow_on_edit_select_all(gpointer data);
static void _noteswindow_on_edit_delete(gpointer data);
static void _noteswindow_on_edit_preferences(gpointer data);
/* help menu */
static void _noteswindow_on_help_about(gpointer data);
#endif
/* constants */
/* accelerators */
static const DesktopAccel _notes_accel[] =
{
#ifdef EMBEDDED
{ G_CALLBACK(_noteswindow_on_close), GDK_CONTROL_MASK, GDK_KEY_W },
{ G_CALLBACK(_noteswindow_on_edit), GDK_CONTROL_MASK, GDK_KEY_E },
{ G_CALLBACK(_noteswindow_on_new), GDK_CONTROL_MASK, GDK_KEY_N },
{ G_CALLBACK(_noteswindow_on_preferences), GDK_CONTROL_MASK, GDK_KEY_P },
#endif
{ NULL, 0, 0 }
};
#ifndef EMBEDDED
/* menubar */
static const DesktopMenu _file_menu[] =
{
{ N_("_New"), G_CALLBACK(_noteswindow_on_file_new), GTK_STOCK_NEW,
GDK_CONTROL_MASK, GDK_KEY_N },
{ N_("_Edit"), G_CALLBACK(_noteswindow_on_file_edit), GTK_STOCK_EDIT,
GDK_CONTROL_MASK, GDK_KEY_E },
{ "", NULL, NULL, 0, 0 },
{ N_("_Close"), G_CALLBACK(_noteswindow_on_file_close), GTK_STOCK_CLOSE,
GDK_CONTROL_MASK, GDK_KEY_W },
{ NULL, NULL, NULL, 0, 0 }
};
static const DesktopMenu _edit_menu[] =
{
{ N_("Select _All"), G_CALLBACK(_noteswindow_on_edit_select_all),
#if GTK_CHECK_VERSION(2, 10, 0)
GTK_STOCK_SELECT_ALL,
#else
"edit-select-all",
#endif
GDK_CONTROL_MASK, GDK_KEY_A },
{ "", NULL, NULL, 0, 0 },
{ N_("_Delete"), G_CALLBACK(_noteswindow_on_edit_delete),
GTK_STOCK_DELETE, 0, 0 },
{ "", NULL, NULL, 0, 0 },
{ N_("_Preferences"), G_CALLBACK(_noteswindow_on_edit_preferences),
GTK_STOCK_PREFERENCES, GDK_CONTROL_MASK, GDK_KEY_P },
{ NULL, NULL, NULL, 0, 0 }
};
static const DesktopMenu _help_menu[] =
{
{ N_("_About"), G_CALLBACK(_noteswindow_on_help_about),
#if GTK_CHECK_VERSION(2, 6, 0)
GTK_STOCK_ABOUT, 0, 0 },
#else
NULL, 0, 0 },
#endif
{ NULL, NULL, NULL, 0, 0 }
};
static const DesktopMenubar _menubar[] =
{
{ N_("_File"), _file_menu },
{ N_("_Edit"), _edit_menu },
{ N_("_Help"), _help_menu },
{ NULL, NULL },
};
#endif
/* public */
/* functions */
/* noteswindow_new */
NotesWindow * noteswindow_new(void)
{
NotesWindow * notes;
GtkAccelGroup * group;
GtkWidget * vbox;
GtkWidget * widget;
if((notes = malloc(sizeof(*notes))) == NULL)
return NULL;
notes->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
group = gtk_accel_group_new();
notes->notes = notes_new(notes->window, group);
/* check for errors */
if(notes->notes == NULL)
{
noteswindow_delete(notes);
g_object_unref(group);
return NULL;
}
desktop_accel_create(_notes_accel, notes, group);
gtk_window_add_accel_group(GTK_WINDOW(notes->window), group);
g_object_unref(group);
gtk_window_set_default_size(GTK_WINDOW(notes->window), 640, 480);
#if GTK_CHECK_VERSION(2, 6, 0)
gtk_window_set_icon_name(GTK_WINDOW(notes->window), "notes");
#endif
gtk_window_set_title(GTK_WINDOW(notes->window), _("Notes"));
g_signal_connect_swapped(notes->window, "delete-event", G_CALLBACK(
_noteswindow_on_closex), notes);
vbox = gtk_vbox_new(FALSE, 0);
#ifndef EMBEDDED
/* menubar */
widget = desktop_menubar_create(_menubar, notes, group);
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
#endif
widget = notes_get_widget(notes->notes);
gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 0);
/* statusbar */
notes->statusbar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox), notes->statusbar, FALSE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(notes->window), vbox);
gtk_widget_show_all(notes->window);
return notes;
}
/* noteswindow_delete */
void noteswindow_delete(NotesWindow * notes)
{
if(notes->notes != NULL)
notes_delete(notes->notes);
gtk_widget_destroy(notes->window);
free(notes);
}
/* private */
/* functions */
/* callbacks */
/* noteswindow_on_close */
static void _noteswindow_on_close(gpointer data)
{
NotesWindow * notes = data;
_noteswindow_on_closex(notes);
}
/* noteswindow_on_closex */
static gboolean _noteswindow_on_closex(gpointer data)
{
NotesWindow * notes = data;
gtk_widget_hide(notes->window);
gtk_main_quit();
return TRUE;
}
/* noteswindow_on_edit */
static void _noteswindow_on_edit(gpointer data)
{
NotesWindow * notes = data;
notes_note_edit(notes->notes);
}
/* noteswindow_on_new */
static void _noteswindow_on_new(gpointer data)
{
NotesWindow * notes = data;
notes_note_add(notes->notes, NULL);
}
/* noteswindow_on_preferences */
static void _noteswindow_on_preferences(gpointer data)
{
NotesWindow * notes = data;
notes_show_preferences(notes->notes, TRUE);
}
#ifndef EMBEDDED
/* file menu */
/* noteswindow_on_file_close */
static void _noteswindow_on_file_close(gpointer data)
{
NotesWindow * notes = data;
_noteswindow_on_close(notes);
}
/* noteswindow_on_file_edit */
static void _noteswindow_on_file_edit(gpointer data)
{
NotesWindow * notes = data;
_noteswindow_on_edit(notes);
}
/* noteswindow_on_file_new */
static void _noteswindow_on_file_new(gpointer data)
{
NotesWindow * notes = data;
_noteswindow_on_new(notes);
}
/* edit menu */
/* noteswindow_on_edit_delete */
static void _noteswindow_on_edit_delete(gpointer data)
{
NotesWindow * notes = data;
notes_note_delete_selected(notes->notes);
}
/* noteswindow_on_edit_preferences */
static void _noteswindow_on_edit_preferences(gpointer data)
{
NotesWindow * notes = data;
_noteswindow_on_preferences(notes);
}
/* noteswindow_on_edit_select_all */
static void _noteswindow_on_edit_select_all(gpointer data)
{
NotesWindow * notes = data;
notes_note_select_all(notes->notes);
}
/* help menu */
/* noteswindow_on_help_about */
static void _noteswindow_on_help_about(gpointer data)
{
NotesWindow * notes = data;
notes_about(notes->notes);
}
#endif

45
src/window.h Normal file
View File

@ -0,0 +1,45 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef NOTES_WINDOW_H
# define NOTES_WINDOW_H
/* NotesWindow */
/* public */
/* types */
typedef struct _NotesWindow NotesWindow;
/* functions */
NotesWindow * noteswindow_new(void);
void noteswindow_delete(NotesWindow * notes);
#endif /* !NOTES_WINDOW_H */

125
tools/notes.c Normal file
View File

@ -0,0 +1,125 @@
/* $Id$ */
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Notes */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#define EMBEDDED
#include <stdlib.h>
#include <Desktop/Mailer/plugin.h>
#include "../src/note.c"
#include "../src/noteedit.c"
#include "../src/notes.c"
/* Mailing-lists */
/* private */
/* types */
typedef struct _MailerPlugin NotesPlugin;
struct _MailerPlugin
{
MailerPluginHelper * helper;
Notes * notes;
/* widgets */
GtkWidget * widget;
GtkWidget * view;
};
/* protected */
/* prototypes */
/* plug-in */
static MailerPlugin * _notes_init(MailerPluginHelper * helper);
static void _notes_destroy(NotesPlugin * notes);
static GtkWidget * _notes_get_widget(NotesPlugin * notes);
/* public */
/* variables */
/* plug-in */
MailerPluginDefinition plugin =
{
"Notes",
"notes",
NULL,
_notes_init,
_notes_destroy,
_notes_get_widget,
NULL
};
/* protected */
/* functions */
/* plug-in */
/* notes_init */
static MailerPlugin * _notes_init(MailerPluginHelper * helper)
{
NotesPlugin * notes;
GtkWidget * widget;
size_t i;
if((notes = malloc(sizeof(*notes))) == NULL)
return NULL;
if((notes->notes = notes_new(NULL, NULL)) == NULL)
{
_notes_destroy(notes);
return NULL;
}
notes->helper = helper;
notes->widget = gtk_vbox_new(FALSE, 4);
widget = notes_get_widget(notes->notes);
gtk_box_pack_start(GTK_BOX(notes->widget), widget, TRUE, TRUE, 0);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(notes->notes->view),
FALSE);
for(i = 0; i < ND_COL_COUNT; i++)
if(notes->notes->columns[i] != NULL && i != ND_COL_TITLE)
gtk_tree_view_column_set_visible(notes->notes->columns[i],
FALSE);
gtk_widget_show_all(notes->widget);
return notes;
}
/* notes_destroy */
static void _notes_destroy(NotesPlugin * notes)
{
if(notes->notes != NULL)
notes_delete(notes->notes);
free(notes);
}
/* notes_get_widget */
static GtkWidget * _notes_get_widget(NotesPlugin * notes)
{
return notes->widget;
}

13
tools/project.conf Normal file
View File

@ -0,0 +1,13 @@
targets=notes
cflags_force=`pkg-config --cflags libDesktop Mailer`
cflags=-W -Wall -g -O2 -pedantic -fPIC -D_FORTIFY_SOURCE=2 -fstack-protector-all
ldflags_force=`pkg-config --libs libDesktop`
dist=Makefile
[notes]
type=plugin
sources=notes.c
install=$(LIBDIR)/Mailer/plugins
[notes.c]
depends=../src/note.c,../src/noteedit.c,../src/notes.c