Initial import of DeforaOS Notes
This is forked from DeforaOS Todo.
This commit is contained in:
commit
e54e881eee
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
Makefile
|
||||
/config.h
|
||||
/config.sh
|
||||
*~
|
||||
*.a
|
||||
*.dll
|
||||
*.dylib
|
||||
*.o
|
||||
*.so
|
||||
*.so.*
|
25
COPYING
Normal file
25
COPYING
Normal 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.
|
10
data/deforaos-notes.desktop
Normal file
10
data/deforaos-notes.desktop
Normal 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
4
data/project.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
dist=Makefile,deforaos-notes.desktop
|
||||
|
||||
[deforaos-notes.desktop]
|
||||
install=$(PREFIX)/share/applications
|
2
po/.gitignore
vendored
Normal file
2
po/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/Notes.pot
|
||||
/*.mo
|
4
po/POTFILES
Normal file
4
po/POTFILES
Normal file
|
@ -0,0 +1,4 @@
|
|||
../src/main.c
|
||||
../src/noteedit.c
|
||||
../src/notes.c
|
||||
../src/window.c
|
122
po/es.po
Normal file
122
po/es.po
Normal 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
122
po/fr.po
Normal 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
210
po/gettext.sh
Executable 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
19
po/project.conf
Normal 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
6
project.conf
Normal 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
1
src/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/notes
|
116
src/main.c
Normal file
116
src/main.c
Normal 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
202
src/note.c
Normal 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
61
src/note.h
Normal 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
163
src/noteedit.c
Normal 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
47
src/noteedit.h
Normal 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
783
src/notes.c
Normal 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(¬es->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, ¬e, -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, ¬e, -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, ¬e, -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, ¬e, -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, ¬e, -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, ¬e, -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
71
src/notes.h
Normal 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
29
src/project.conf
Normal 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
321
src/window.c
Normal 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
45
src/window.h
Normal 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
125
tools/notes.c
Normal 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
13
tools/project.conf
Normal 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
|
Loading…
Reference in New Issue
Block a user