Initial import of gparts from gparts-source.tar.gz

This commit is contained in:
Edward Hennessy 2009-03-25 21:21:29 -04:00
commit d2a0cc119f
78 changed files with 53598 additions and 0 deletions

1
AUTHORS Normal file
View File

@ -0,0 +1 @@
Required AUTHORS file

1
ChangeLog Normal file
View File

@ -0,0 +1 @@
Required ChangeLog file

98
INSTALL Normal file
View File

@ -0,0 +1,98 @@
gEDA
GPL Electronic Design Automation
------------------------------------------------------------------------------
REQUIREMENTS
------------
Building GParts requires the following packages:
gcc
libgtk2.0-dev
pkg-config
Additionally, GParts requires a database for the back-end. Currently, GParts
can use either MySQL or PostgreSQL. In order to use MySQL, the packages listed
below must be installed. The mysql-server package may not be required if
configured to use a remote server.
libmysqlclient15-dev
mysql-client
mysql-server
In order to use PostgreSQL, the following packages must be installed:
(TODO: PostgreSQL not supported yet.)
libpq-dev
postgresql
Of course, installing all packages before building allows the application to
use either database for the back-end.
BUILDING GPARTS
---------------
TODO: Finish documentation
DATABASE CREATION (MySQL)
-------------------------
Install MySQL.
Tested under 5.0.51a-3ubuntu5.1.
To create the database, enter MySQL command line mode as root and enter the SQL
commands below. Placing the password in the command line could leave the
password in the command line history. Using only the -p option will cause
mysql to prompt for the password and avoid this situation. A different
database name, other than gparts, can be specified by the user. Using
different names, the user can create multiple GPart databases. Additionally,
user accounts may need to be created.
$ mysql -u root -p
mysql> create database GParts;
mysql> use GParts;
mysql> grant all privileges on *.* to 'user'@'localhost'
identified by 'password';
After creating the database, the base tables and part-specific tables must be
created. All the SQL commands to perform these operations are included in the
distributed files. Enter the following commands at the MySQL command line.
mysql> source sql/mysql/create-create.sql
mysql> source sql/mysql/create-categories.sql
mysql> source sql/mysql/create-discretes.sql
mysql> source sql/mysql/create-passives.sql
Begin loading the database, starting with package data. The package data must
be loaded before any parts.
mysql> source data/packages.sql
The package includes a tool to parse the symbol libraries and generate an
SQL file for import into the database. Run the tool at the shell prompt, then
import the file from an MySQL prompt. The tool requires the root gEDA
directory as the only parameter. Your gEDA root directory may be different than
below. The symbol data must be loaded before any parts.
$ tools/symbols.py /usr/share/gEDA >tmp/symbols.sql
mysql> source tmp/symbols.sql
The package includes a script to generate some sample part data. Similar to
the symbol tool, run the script at the shell prompt, then import the data at
the MySQL prompt.
$ data/parts-bourns.py >tmp/parts-bourns.sql
mysql> source tmp/parts-bourns.sql
DATABASE CREATION (PostgreSQL)
------------------------------
TODO: Finish implementation
DATABASE CREATION (SQLite)
------------------------------
TODO: Finish implementation

1
Makefile.am Normal file
View File

@ -0,0 +1 @@
SUBDIRS = src

1
NEWS Normal file
View File

@ -0,0 +1 @@
Required NEWS file

1
README Normal file
View File

@ -0,0 +1 @@
Required README file

8764
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

4
autogen.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
autoreconf --install --verbose --force

142
compile Executable file
View File

@ -0,0 +1,142 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2005-05-14.22
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
esac
ofile=
cfile=
eat=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

109
configure.ac Normal file
View File

@ -0,0 +1,109 @@
AC_INIT([gparts],[0.0])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_CC
AC_PROG_CC_C_O
AM_PROG_LIBTOOL
## Checking for programs
AC_PATH_PROG([DOXYGEN], 'doxygen')
if test $DOXYGEN; then :; else
AC_MSG_WARN([Unable to locate doxygen. Documentation will not be created.])
fi
AC_PATH_PROG([PKG_CONFIG],'pkg-config')
if test $PKG_CONFIG; then :; else
AC_MSG_ERROR([Unable to locate pkg-config. Make sure pkg-config is installed and in the path.])
fi
## GLIB
##
## GTK's CFLAGS and LIBS includes GLib's, so including them is redundant.
##
GLIB_VERSION=`$PKG_CONFIG glib-2.0 --modversion`
GLIB_CFLAGS=`$PKG_CONFIG glib-2.0 --cflags`
GLIB_LIBS=`$PKG_CONFIG glib-2.0 --libs`
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
## GModule
##
## GModule is needed to dynamically load database interfaces.
##
GMODULE_VERSION=`$PKG_CONFIG gmodule-2.0 --modversion`
GMODULE_CFLAGS=`$PKG_CONFIG gmodule-2.0 --cflags`
GMODULE_LIBS=`$PKG_CONFIG gmodule-2.0 --libs`
AC_SUBST(GMODULE_CFLAGS)
AC_SUBST(GMODULE_LIBS)
## GTK
##
GTK_VERSION=`$PKG_CONFIG gtk+-2.0 --modversion`
GTK_CFLAGS=`$PKG_CONFIG gtk+-2.0 --cflags`
GTK_LIBS=`$PKG_CONFIG gtk+-2.0 --libs`
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
## MySQL
##
## Building the interface library for MySQL is optional.
##
AC_PATH_PROG([MYSQL_CONFIG],'mysql_config')
if test $MYSQL_CONFIG; then
MYSQL_VERSION=`$MYSQL_CONFIG --version`
MYSQL_CFLAGS=`$MYSQL_CONFIG --cflags`
MYSQL_LIBS=`$MYSQL_CONFIG --libs`
MYSQL_LDADD='libgparts-mysql.la'
else
AC_MSG_WARN([Unable to locate mysql_config. Make sure MySQL development libraries are installed and mysql_config is in the path.])
fi
AC_SUBST(MYSQL_CFLAGS)
AC_SUBST(MYSQL_LIBS)
AC_SUBST(MYSQL_LDADD)
## PostgreSQL
##
## Building the interface library for PostgreSQL is optional.
##
AC_PATH_PROG([POSTGRESQL_CONFIG],'pg_config')
if test $POSTGRESQL_CONFIG; then
POSTGRESQL_VERSION=`$PG_CONFIG --version`
POSTGRESQL_CFLAGS=`$PG_CONFIG --cflags`
POSTGRESQL_LIBS=`$PG_CONFIG --libs`
# PG_LDADD='libgparts-postgresql.la'
else
AC_MSG_WARN([Unable to locate pg_config. Make sure PostgreSQL development libraries are installed and pg_config is in the path.])
fi
AC_SUBST(POSTGRESQL_CFLAGS)
AC_SUBST(POSTGRESQL_LIBS)
AC_SUBST(POSTGRESQL_LDADD)
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
AC_MSG_RESULT([
****************** SUMMARY FOR gparts CONFIGURATION ******************
GLib
Installed Version $GLIB_VERSION
GModule
Installed Version $GMODULE_VERSION
GTK
Installed Version $GTK_VERSION
MySQL
Installed Version $MYSQL_VERSION
PostgreSQL
Installed Version $POSTGRESQL_VERSION
])

File diff suppressed because it is too large Load Diff

182
data/packages.sql Normal file
View File

@ -0,0 +1,182 @@
-- Adds packaging (case) data to the GParts database.
--
-- PACKAGE NAMES
-- Prefer uppercase in all package names.
--
-- CAPACITORS
-- EIA form factors include the maximum height: 'EIA-7343-43'.
--
-- CHIP COMPONENTS
-- Chip components include the metric designation in parenthesis to reduce
-- confusion. For example, an '0603' package is named '0603(1806)'.
--
-- DIODES
-- The DO-214 packages include the alternate name in parenthesis. For example
-- 'DO-214AB(SMC)'. This additional information gets presented to the user.
--
CALL AddPackage(
"0201(0603)",
'SMT'
);
CALL AddPackage(
"0402(1005)",
'SMT'
);
CALL AddPackage(
"0603(1608)",
'SMT'
);
CALL AddPackage(
"0805(2012)",
'SMT'
);
CALL AddPackage(
"1005(2512)",
'SMT'
);
CALL AddPackage(
"1206(3216)",
'SMT'
);
CALL AddPackage(
"1806(4516)",
'SMT'
);
CALL AddPackage(
"1812(4532)",
'SMT'
);
CALL AddPackage(
"2010(5025)",
'SMT'
);
CALL AddPackage(
"2512(6332)",
'SMT'
);
CALL AddPackage(
"DO-214AA(SMB)",
'SMT'
);
CALL AddPackage(
"DO-214AB(SMC)",
'SMT'
);
CALL AddPackage(
"DO-214AC(SMA)",
'SMT'
);
CALL AddPackage(
"EIA-3216-18",
'SMT'
);
CALL AddPackage(
"EIA-3528-21",
'SMT'
);
CALL AddPackage(
"EIA-7343-20",
'SMT'
);
CALL AddPackage(
"EIA-6032-28",
'SMT'
);
CALL AddPackage(
"EIA-7343-31",
'SMT'
);
CALL AddPackage(
"EIA-7343-43",
'SMT'
);
CALL AddPackage(
"SC-59",
'SMT'
);
CALL AddPackage(
"SC-70",
'SMT'
);
CALL AddPackage(
"SC-75",
'SMT'
);
CALL AddPackage(
"SC-88A",
'SMT'
);
CALL AddPackage(
"SOD-123",
'SMT'
);
CALL AddPackage(
"SOD-323",
'SMT'
);
CALL AddPackage(
"SOD-523",
'SMT'
);
CALL AddPackage(
"SOD-723",
'SMT'
);
CALL AddPackage(
"SOD-923",
'SMT'
);
CALL AddPackage(
"SOT-23",
'SMT'
);
CALL AddPackage(
"SOT-363",
'SMT'
);
CALL AddPackage(
"SOT-563",
'SMT'
);
CALL AddPackage(
"SOT-723",
'SMT'
);
CALL AddPackage(
"TO-92",
'TH'
);

667
data/parts-bourns.py Executable file
View File

@ -0,0 +1,667 @@
#!/usr/bin/python
##############################################################################
##
## Create sample parts from Bourns for the GParts database.
##
##############################################################################
print "CALL AddCompany("
print " 'Bourns'"
print " );"
print
##############################################################################
##
## CR0603/0805/1206 Chip Resistors
##
##############################################################################
packages = [
( '0603', '0603(1608)' ),
( '0805', '0805(2012)' ),
( '1206', '1206(3216)' )
]
resistances = [
( '10R0', 10.0 ),
( '10R2', 10.2 ),
( '10R5', 10.5 ),
( '10R7', 10.7 ),
( '11R0', 11.0 ),
( '11R3', 11.3 ),
( '11R5', 11.5 ),
( '11R8', 11.8 ),
( '12R0', 12.0 ),
( '12R1', 12.1 ),
( '12R4', 12.4 ),
( '12R7', 12.7 ),
( '13R0', 13.0 ),
( '13R3', 13.3 ),
( '13R7', 13.7 ),
( '14R0', 14.0 ),
( '14R3', 14.3 ),
( '14R7', 14.7 ),
( '15R0', 15.0 ),
( '15R4', 15.4 ),
( '15R8', 15.8 ),
( '16R0', 16.0 ),
( '16R2', 16.2 ),
( '16R5', 16.5 ),
( '16R9', 16.9 ),
( '17R4', 17.4 ),
( '17R8', 17.8 ),
( '18R0', 18.0 ),
( '18R2', 18.2 ),
( '18R7', 18.7 ),
( '19R1', 19.1 ),
( '19R6', 19.6 ),
( '20R0', 20.0 ),
( '20R5', 20.5 ),
( '21R0', 21.0 ),
( '21R5', 21.5 ),
( '22R0', 22.0 ),
( '22R1', 22.1 ),
( '22R6', 22.6 ),
( '23R2', 23.2 ),
( '23R7', 23.7 ),
( '24R0', 24.0 ),
( '24R3', 24.3 ),
( '24R9', 24.9 ),
( '25R5', 25.5 ),
( '26R1', 26.1 ),
( '26R7', 26.7 ),
( '27R0', 27.0 ),
( '27R4', 27.4 ),
( '28R0', 28.0 ),
( '28R7', 28.7 ),
( '29R4', 29.4 ),
( '30R0', 30.0 ),
( '30R1', 30.1 ),
( '30R9', 30.9 ),
( '31R6', 31.6 ),
( '32R4', 32.4 ),
( '33R0', 33.0 ),
( '33R2', 33.2 ),
( '34R0', 34.0 ),
( '34R8', 34.8 ),
( '35R7', 35.7 ),
( '36R0', 36.0 ),
( '36R5', 35.6 ),
( '37R4', 37.4 ),
( '38R3', 38.3 ),
( '39R0', 39.0 ),
( '39R2', 39.2 ),
( '40R2', 40.2 ),
( '41R2', 41.2 ),
( '42R2', 42.2 ),
( '43R0', 43.0 ),
( '43R2', 43.2 ),
( '44R2', 44.2 ),
( '45R3', 45.3 ),
( '46R4', 46.4 ),
( '47R0', 47.0 ),
( '47R5', 47.5 ),
( '48R7', 48.7 ),
( '49R9', 49.9 ),
( '51R0', 51.0 ),
( '51R1', 51.1 ),
( '52R3', 52.3 ),
( '53R6', 53.6 ),
( '54R9', 54.9 ),
( '56R0', 56.0 ),
( '56R2', 56.2 ),
( '57R6', 57.6 ),
( '59R0', 59.0 ),
( '60R4', 60.4 ),
( '61R9', 61.9 ),
( '62R0', 62.0 ),
( '63R4', 63.4 ),
( '64R9', 64.9 ),
( '66R5', 66.5 ),
( '68R0', 68.0 ),
( '68R1', 68.1 ),
( '69R8', 69.8 ),
( '71R5', 71.5 ),
( '73R2', 73.2 ),
( '75R0', 75.0 ),
( '76R8', 76.8 ),
( '78R7', 78.7 ),
( '80R6', 80.6 ),
( '82R0', 82.0 ),
( '82R5', 82.5 ),
( '84R5', 84.5 ),
( '86R6', 86.6 ),
( '88R7', 88.7 ),
( '90R9', 90.9 ),
( '91R0', 91.0 ),
( '93R1', 93.1 ),
( '95R3', 95.3 ),
( '97R0', 97.6 ),
( '1000', 100.0 ),
( '1020', 102.0 ),
( '1050', 105.0 ),
( '1070', 107.0 ),
( '1100', 110.0 ),
( '1130', 113.0 ),
( '1150', 115.0 ),
( '1180', 118.0 ),
( '1200', 120.0 ),
( '1210', 121.0 ),
( '1240', 124.0 ),
( '1270', 127.0 ),
( '1300', 130.0 ),
( '1330', 133.0 ),
( '1370', 137.0 ),
( '1400', 140.0 ),
( '1430', 143.0 ),
( '1470', 147.0 ),
( '1500', 150.0 ),
( '1540', 154.0 ),
( '1580', 158.0 ),
( '1600', 160.0 ),
( '1620', 162.0 ),
( '1650', 165.0 ),
( '1690', 169.0 ),
( '1740', 174.0 ),
( '1780', 178.0 ),
( '1800', 180.0 ),
( '1820', 182.0 ),
( '1870', 187.0 ),
( '1910', 191.0 ),
( '1960', 196.0 ),
( '2000', 200.0 ),
( '2050', 205.0 ),
( '2100', 210.0 ),
( '2150', 215.0 ),
( '2200', 220.0 ),
( '2210', 221.0 ),
( '2260', 226.0 ),
( '2320', 232.0 ),
( '2370', 237.0 ),
( '2400', 240.0 ),
( '2430', 243.0 ),
( '2490', 249.0 ),
( '2550', 255.0 ),
( '2610', 261.0 ),
( '2670', 267.0 ),
( '2700', 270.0 ),
( '2740', 274.0 ),
( '2800', 280.0 ),
( '2870', 287.0 ),
( '2940', 294.0 ),
( '3000', 300.0 ),
( '3010', 301.0 ),
( '3090', 309.0 ),
( '3160', 316.0 ),
( '3240', 324.0 ),
( '3300', 330.0 ),
( '3320', 332.0 ),
( '3400', 340.0 ),
( '3480', 348.0 ),
( '3570', 357.0 ),
( '3600', 360.0 ),
( '3650', 356.0 ),
( '3740', 374.0 ),
( '3830', 383.0 ),
( '3900', 390.0 ),
( '3920', 392.0 ),
( '4020', 402.0 ),
( '4120', 412.0 ),
( '4220', 422.0 ),
( '4300', 430.0 ),
( '4320', 432.0 ),
( '4420', 442.0 ),
( '4530', 453.0 ),
( '4640', 464.0 ),
( '4700', 470.0 ),
( '4750', 475.0 ),
( '4870', 487.0 ),
( '4990', 499.0 ),
( '5100', 510.0 ),
( '5110', 511.0 ),
( '5230', 523.0 ),
( '5360', 536.0 ),
( '5490', 549.0 ),
( '5600', 560.0 ),
( '5620', 562.0 ),
( '5760', 576.0 ),
( '5900', 590.0 ),
( '6040', 604.0 ),
( '6190', 619.0 ),
( '6200', 620.0 ),
( '6340', 634.0 ),
( '6490', 649.0 ),
( '6650', 665.0 ),
( '6800', 680.0 ),
( '6810', 681.0 ),
( '6980', 698.0 ),
( '7150', 715.0 ),
( '7320', 732.0 ),
( '7500', 750.0 ),
( '7680', 768.0 ),
( '7870', 787.0 ),
( '8060', 806.0 ),
( '8200', 820.0 ),
( '8250', 825.0 ),
( '8450', 845.0 ),
( '8660', 866.0 ),
( '8870', 887.0 ),
( '9090', 909.0 ),
( '9100', 910.0 ),
( '9310', 931.0 ),
( '9530', 953.0 ),
( '9760', 976.0 ),
( '1001', 1000.0 ),
( '1021', 1020.0 ),
( '1051', 1050.0 ),
( '1071', 1070.0 ),
( '1101', 1100.0 ),
( '1131', 1130.0 ),
( '1151', 1150.0 ),
( '1181', 1180.0 ),
( '1201', 1200.0 ),
( '1211', 1210.0 ),
( '1241', 1240.0 ),
( '1271', 1270.0 ),
( '1301', 1300.0 ),
( '1331', 1330.0 ),
( '1371', 1370.0 ),
( '1401', 1400.0 ),
( '1431', 1430.0 ),
( '1471', 1470.0 ),
( '1501', 1500.0 ),
( '1541', 1540.0 ),
( '1581', 1580.0 ),
( '1601', 1600.0 ),
( '1621', 1620.0 ),
( '1651', 1650.0 ),
( '1691', 1690.0 ),
( '1741', 1740.0 ),
( '1781', 1780.0 ),
( '1801', 1800.0 ),
( '1821', 1820.0 ),
( '1871', 1870.0 ),
( '1911', 1910.0 ),
( '1961', 1960.0 ),
( '2001', 2000.0 ),
( '2051', 2050.0 ),
( '2101', 2100.0 ),
( '2151', 2150.0 ),
( '2201', 2200.0 ),
( '2211', 2210.0 ),
( '2261', 2260.0 ),
( '2321', 2320.0 ),
( '2371', 2370.0 ),
( '2401', 2400.0 ),
( '2431', 2430.0 ),
( '2491', 2490.0 ),
( '2551', 2550.0 ),
( '2611', 2610.0 ),
( '2671', 2670.0 ),
( '2701', 2700.0 ),
( '2741', 2740.0 ),
( '2801', 2800.0 ),
( '2871', 2870.0 ),
( '2941', 2940.0 ),
( '3001', 3000.0 ),
( '3011', 3010.0 ),
( '3091', 3090.0 ),
( '3161', 3160.0 ),
( '3241', 3240.0 ),
( '3301', 3300.0 ),
( '3321', 3320.0 ),
( '3401', 3400.0 ),
( '3481', 3480.0 ),
( '3571', 3570.0 ),
( '3601', 3600.0 ),
( '3651', 3560.0 ),
( '3741', 3740.0 ),
( '3831', 3830.0 ),
( '3901', 3900.0 ),
( '3921', 3920.0 ),
( '4021', 4020.0 ),
( '4121', 4120.0 ),
( '4221', 4220.0 ),
( '4301', 4300.0 ),
( '4321', 4320.0 ),
( '4421', 4420.0 ),
( '4531', 4530.0 ),
( '4641', 4640.0 ),
( '4701', 4700.0 ),
( '4751', 4750.0 ),
( '4871', 4870.0 ),
( '4991', 4990.0 ),
( '5101', 5100.0 ),
( '5111', 5110.0 ),
( '5231', 5230.0 ),
( '5361', 5360.0 ),
( '5491', 5490.0 ),
( '5601', 5600.0 ),
( '5621', 5620.0 ),
( '5761', 5760.0 ),
( '5901', 5900.0 ),
( '6041', 6040.0 ),
( '6191', 6190.0 ),
( '6201', 6200.0 ),
( '6341', 6340.0 ),
( '6491', 6490.0 ),
( '6651', 6650.0 ),
( '6801', 6800.0 ),
( '6811', 6810.0 ),
( '6981', 6980.0 ),
( '7151', 7150.0 ),
( '7321', 7320.0 ),
( '7501', 7500.0 ),
( '7681', 7680.0 ),
( '7871', 7870.0 ),
( '8061', 8060.0 ),
( '8201', 8200.0 ),
( '8251', 8250.0 ),
( '8451', 8450.0 ),
( '8661', 8660.0 ),
( '8871', 8870.0 ),
( '9091', 9090.0 ),
( '9101', 9100.0 ),
( '9311', 9310.0 ),
( '9531', 9530.0 ),
( '9761', 9760.0 ),
( '1002', 10000.0 ),
( '1022', 10200.0 ),
( '1052', 10500.0 ),
( '1072', 10700.0 ),
( '1102', 11000.0 ),
( '1132', 11300.0 ),
( '1152', 11500.0 ),
( '1182', 11800.0 ),
( '1202', 12000.0 ),
( '1212', 12100.0 ),
( '1242', 12400.0 ),
( '1272', 12700.0 ),
( '1302', 13000.0 ),
( '1332', 13300.0 ),
( '1372', 13700.0 ),
( '1402', 14000.0 ),
( '1432', 14300.0 ),
( '1472', 14700.0 ),
( '1502', 15000.0 ),
( '1542', 15400.0 ),
( '1582', 15800.0 ),
( '1602', 16000.0 ),
( '1622', 16200.0 ),
( '1652', 16500.0 ),
( '1692', 16900.0 ),
( '1742', 17400.0 ),
( '1782', 17800.0 ),
( '1802', 18000.0 ),
( '1822', 18200.0 ),
( '1872', 18700.0 ),
( '1912', 19100.0 ),
( '1962', 19600.0 ),
( '2002', 20000.0 ),
( '2052', 20500.0 ),
( '2102', 21000.0 ),
( '2152', 21500.0 ),
( '2202', 22000.0 ),
( '2212', 22100.0 ),
( '2262', 22600.0 ),
( '2322', 23200.0 ),
( '2372', 23700.0 ),
( '2402', 24000.0 ),
( '2432', 24300.0 ),
( '2492', 24900.0 ),
( '2552', 25500.0 ),
( '2612', 26100.0 ),
( '2672', 26700.0 ),
( '2702', 27000.0 ),
( '2742', 27400.0 ),
( '2802', 28000.0 ),
( '2872', 28700.0 ),
( '2942', 29400.0 ),
( '3002', 30000.0 ),
( '3012', 30100.0 ),
( '3092', 30900.0 ),
( '3162', 31600.0 ),
( '3242', 32400.0 ),
( '3302', 33000.0 ),
( '3322', 33200.0 ),
( '3402', 34000.0 ),
( '3482', 34800.0 ),
( '3572', 35700.0 ),
( '3602', 36000.0 ),
( '3652', 35600.0 ),
( '3742', 37400.0 ),
( '3832', 38300.0 ),
( '3902', 39000.0 ),
( '3922', 39200.0 ),
( '4022', 40200.0 ),
( '4122', 41200.0 ),
( '4222', 42200.0 ),
( '4302', 43000.0 ),
( '4322', 43200.0 ),
( '4422', 44200.0 ),
( '4532', 45300.0 ),
( '4642', 46400.0 ),
( '4702', 47000.0 ),
( '4752', 47500.0 ),
( '4872', 48700.0 ),
( '4992', 49900.0 ),
( '5102', 51000.0 ),
( '5112', 51100.0 ),
( '5232', 52300.0 ),
( '5362', 53600.0 ),
( '5492', 54900.0 ),
( '5602', 56000.0 ),
( '5622', 56200.0 ),
( '5762', 57600.0 ),
( '5902', 59000.0 ),
( '6042', 60400.0 ),
( '6192', 61900.0 ),
( '6202', 62000.0 ),
( '6342', 63400.0 ),
( '6492', 64900.0 ),
( '6652', 66500.0 ),
( '6802', 68000.0 ),
( '6812', 68100.0 ),
( '6982', 69800.0 ),
( '7152', 71500.0 ),
( '7322', 73200.0 ),
( '7502', 75000.0 ),
( '7682', 76800.0 ),
( '7872', 78700.0 ),
( '8062', 80600.0 ),
( '8202', 82000.0 ),
( '8252', 82500.0 ),
( '8452', 84500.0 ),
( '8662', 86600.0 ),
( '8872', 88700.0 ),
( '9092', 90900.0 ),
( '9102', 91000.0 ),
( '9312', 93100.0 ),
( '9532', 95300.0 ),
( '9762', 97600.0 ),
( '1003', 100000.0 ),
( '1023', 102000.0 ),
( '1053', 105000.0 ),
( '1073', 107000.0 ),
( '1103', 110000.0 ),
( '1133', 113000.0 ),
( '1153', 115000.0 ),
( '1183', 118000.0 ),
( '1203', 120000.0 ),
( '1213', 121000.0 ),
( '1243', 124000.0 ),
( '1273', 127000.0 ),
( '1303', 130000.0 ),
( '1333', 133000.0 ),
( '1373', 137000.0 ),
( '1403', 140000.0 ),
( '1433', 143000.0 ),
( '1473', 147000.0 ),
( '1503', 150000.0 ),
( '1543', 154000.0 ),
( '1583', 158000.0 ),
( '1603', 160000.0 ),
( '1623', 162000.0 ),
( '1653', 165000.0 ),
( '1693', 169000.0 ),
( '1743', 174000.0 ),
( '1783', 178000.0 ),
( '1803', 180000.0 ),
( '1823', 182000.0 ),
( '1873', 187000.0 ),
( '1913', 191000.0 ),
( '1963', 196000.0 ),
( '2003', 200000.0 ),
( '2053', 205000.0 ),
( '2103', 210000.0 ),
( '2153', 215000.0 ),
( '2203', 220000.0 ),
( '2213', 221000.0 ),
( '2263', 226000.0 ),
( '2323', 232000.0 ),
( '2373', 237000.0 ),
( '2403', 240000.0 ),
( '2433', 243000.0 ),
( '2493', 249000.0 ),
( '2553', 255000.0 ),
( '2613', 261000.0 ),
( '2673', 267000.0 ),
( '2703', 270000.0 ),
( '2743', 274000.0 ),
( '2803', 280000.0 ),
( '2873', 287000.0 ),
( '2943', 294000.0 ),
( '3003', 300000.0 ),
( '3013', 301000.0 ),
( '3093', 309000.0 ),
( '3163', 316000.0 ),
( '3243', 324000.0 ),
( '3303', 330000.0 ),
( '3323', 332000.0 ),
( '3403', 340000.0 ),
( '3483', 348000.0 ),
( '3573', 357000.0 ),
( '3603', 360000.0 ),
( '3653', 356000.0 ),
( '3743', 374000.0 ),
( '3833', 383000.0 ),
( '3903', 390000.0 ),
( '3923', 392000.0 ),
( '4023', 402000.0 ),
( '4123', 412000.0 ),
( '4223', 422000.0 ),
( '4303', 430000.0 ),
( '4323', 432000.0 ),
( '4423', 442000.0 ),
( '4533', 453000.0 ),
( '4643', 464000.0 ),
( '4703', 470000.0 ),
( '4753', 475000.0 ),
( '4873', 487000.0 ),
( '4993', 499000.0 ),
( '5103', 510000.0 ),
( '5113', 511000.0 ),
( '5233', 523000.0 ),
( '5363', 536000.0 ),
( '5493', 549000.0 ),
( '5603', 560000.0 ),
( '5623', 562000.0 ),
( '5763', 576000.0 ),
( '5903', 590000.0 ),
( '6043', 604000.0 ),
( '6193', 619000.0 ),
( '6203', 620000.0 ),
( '6343', 634000.0 ),
( '6493', 649000.0 ),
( '6653', 665000.0 ),
( '6803', 680000.0 ),
( '6813', 681000.0 ),
( '6983', 698000.0 ),
( '7153', 715000.0 ),
( '7323', 732000.0 ),
( '7503', 750000.0 ),
( '7683', 768000.0 ),
( '7873', 787000.0 ),
( '8063', 806000.0 ),
( '8203', 820000.0 ),
( '8253', 825000.0 ),
( '8453', 845000.0 ),
( '8663', 866000.0 ),
( '8873', 887000.0 ),
( '9093', 909000.0 ),
( '9103', 910000.0 ),
( '9313', 931000.0 ),
( '9533', 953000.0 ),
( '9763', 976000.0 ),
( '1004', 1000000.0 )
]
for package in packages:
for resistance in resistances:
print "CALL AddResistor("
print " 'Bourns',"
print " 'CR%s-FX-%sELF'," % ( package[0], resistance[0] )
print " '%s'," % package[1]
print " 'RESISTOR',"
print " %f," % resistance[1]
print " %f" % 0.01
print " );"
print
##############################################################################
##
## CD0603/1005-Z Surface Mount Zener Diode Series
##
##############################################################################
packages = [
( '0603', '0603(1608)' ),
( '1005', '1005(2512)' )
]
voltages = [
( '2', 2.0 ),
( '2V2', 2.2 ),
( '2V4', 2.4 ),
( '2V7', 2.7 ),
( '3', 3.0 ),
( '3V3', 3.3 ),
( '3V6', 3.6 ),
( '3V9', 3.9 ),
( '4V3', 4.3 ),
( '4V7', 4.7 ),
( '5V1', 5.1 ),
( '5V6', 5.6 ),
( '6V2', 6.2 ),
( '6V8', 6.8 ),
( '7V5', 7.5 ),
( '8V2', 8.2 ),
( '9V1', 9.1 ),
( '10', 10.0 ),
( '11', 11.0 ),
( '12', 12.0 ),
( '13', 13.0 ),
( '15', 15.0 ),
( '16', 16.0 ),
( '18', 18.0 ),
( '20', 20.0 ),
( '22', 22.0 ),
( '24', 24.0 ),
( '27', 27.0 ),
( '30', 30.0 ),
( '33', 33.0 ),
( '36', 36.0 ),
( '39', 39.0 )
]
for package in packages:
for voltage in voltages:
print "CALL AddZenerDiode("
print " 'Bourns',"
print " 'CD%s-Z%s'," % ( package[0], voltage[0] )
print " '%s'," % package[1]
print " 'ZENER_DIODE',"
print " %f" % voltage[1]
print " );"
print

56
data/parts-vishay-sprague.py Executable file
View File

@ -0,0 +1,56 @@
#!/usr/bin/python
##
##
##
##
print "CALL AddCompany("
print " 'Vishay-Sprague'"
print " );"
print
##############################################################################
##
## 593D Series Solid Tantalum Chip Capacitors
##
##############################################################################
capacitances = [
( "107", 0.0 ),
( "108", 0.0 ),
( "109", 0.0 ),
( "110", 0.0 )
]
packages = [
( "A", "EIA-3216-18" ),
( "B", "EIA-3528-21" ),
( "C", "EIA-6032-28" ),
( "D", "EIA-7343-31" ),
( "E", "EIA-7343-43" ),
( "V", "EIA-7343-20" )
]
voltages = [
( "004", 4.0 ),
( "6R3", 6.3 ),
( "010", 10.0 ),
( "016", 16.0 ),
( "020", 20.0 ),
( "025", 25.0 ),
( "035", 35.0 ),
( "050", 50.0 )
]
for capacitance in capacitances:
for package in packages:
for voltage in voltages:
print "CALL AddCapacitor("
print " 'Vishay-Sprague',"
print " '593D-%sX9%s%s'," % ( capacitance[0], voltage[0], package[0] )
print " '%s'," % package[1]
print " 'CAPACITOR',"
print " %f" % capacitance[1]
print " );"
print

30
sql/create-all.sql Normal file
View File

@ -0,0 +1,30 @@
-- A simple script to speed up development
--
-- * Destroys existing database
-- * Creates replacement
-- * Loads developer test data
--
-- All the temporary files must be created as shown in the INSTALL document.
--
-- Be in the project root directory and when in MySQL:
--
-- mysql> source sql/create-all.sql
--
drop database GParts;
create database GParts;
use GParts;
source sql/mysql/create-basic.sql;
source sql/mysql/create-discretes.sql;
source sql/mysql/create-passives.sql;
source sql/mysql/create-categories.sql;
source data/packages.sql;
source tmp/symbols.sql
source tmp/parts-bourns.sql;
source tmp/parts-vishay-sprague.sql;
source data/onsemi-switching-diodes.sql;

483
sql/mysql/create-basic.sql Normal file
View File

@ -0,0 +1,483 @@
-- ---------------------------------------------------------------------------
--
-- gEDA - GPL Electronic Design Automation
-- gparts - gEDA Parts Manager
-- Copyright (C) 2009 Edward C. Hennessy
-- Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
--
-- ---------------------------------------------------------------------------
--
-- SQL commands to initially setup the GParts database.
--
CREATE TABLE Category (
CategoryID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
CategoryName VARCHAR(500) NOT NULL,
ViewName VARCHAR(500),
ParentID INTEGER UNSIGNED,
PRIMARY KEY ( CategoryID ),
UNIQUE( CategoryName )
);
-- Create a table for application specific column metadata
--
CREATE TABLE ColumnMeta (
ViewName VARCHAR(500) NOT NULL,
ColumnName VARCHAR(500) NOT NULL,
Units VARCHAR(500),
UNIQUE ( ViewName, ColumnName )
);
-- Create a table to store companies.
--
-- Currently, companies only include manufacturers. In the future, companies
-- could be expanded to include vendors.
--
CREATE TABLE Company (
CompanyID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
CompanyName VARCHAR(500) NOT NULL,
PRIMARY KEY ( CompanyID ),
UNIQUE ( CompanyName )
);
-- Create a table to store devices.
--
-- GParts uses the device attribute from the symbol file to group symbols.
-- Currently, the device attribute offers the only mechanism to group symbols.
--
CREATE TABLE Device (
DeviceID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
DeviceName VARCHAR(500) NOT NULL,
PRIMARY KEY ( DeviceID ),
UNIQUE ( DeviceName )
);
-- Create a table to store documents.
--
-- The GParts database stores documentation for parts, allowing the user
-- quick access to specific information on parts in the database.
--
-- The category field stores a short description of the document type for the
-- user. Categories include datasheet, errata, user manual, etc... The
-- database does not use the category field except for presenting it to the
-- user. Likewise, the title field contains a more detailed description of
-- the document.
--
-- The source URL field specifies where to obtain a copy of the document. This
-- field contains NULL for resources created locally. If the URL becomes
-- invalid, this field can be set to NULL. In this case, if the location field
-- does not contain NULL, the record can persist with a local copy of the
-- document.
--
-- The file location field specifies a local path to the document relative to
-- the gEDA top level directory. This document could either be created locally
-- or be a downloaded copy from the source URL.
--
-- Entities with both source URL and file location containing NULL no longer
-- refer to anything, and can be deleted.
--
CREATE TABLE Document (
DocumentID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Category VARCHAR(500) NOT NULL,
Title VARCHAR(500) NOT NULL,
SourceURL VARCHAR(500) DEFAULT NULL,
FileLocation VARCHAR(500) DEFAULT NULL,
PRIMARY KEY ( DocumentID ),
UNIQUE ( SourceURL ),
UNIQUE ( FileLocation )
);
-- Create a junction table for parts and documents.
--
-- Parts and documents have a many-to-many relationhip. For example, an entire
-- series of simple parts may share a single datasheet, such as resistors.
-- Complex parts may require multiple documents, such as datasheets, user
-- manuals, and errata.
--
CREATE TABLE DocumentPartJ (
DocumentID INTEGER UNSIGNED NOT NULL,
PartID INTEGER UNSIGNED NOT NULL,
PRIMARY KEY ( DocumentID, PartID ),
FOREIGN KEY ( DocumentID ) REFERENCES Document,
FOREIGN KEY ( PartID ) REFERENCES Part
);
-- Create a table for PCB footprints.
--
-- A footprint represents a series of footprints for a particular electronic
-- component's package. The FootprintName gets placed into a heavy symbol as
-- the 'footprint' attribute.
--
CREATE TABLE Footprint (
FootprintID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
FootprintName VARCHAR(500) NOT NULL,
PRIMARY KEY ( FootprintID ),
UNIQUE ( FootprintName )
);
-- Create a table for parts.
--
CREATE TABLE Part (
PartID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
CompanyID INTEGER UNSIGNED NOT NULL,
PartNumber VARCHAR( 500 ) NOT NULL,
DeviceID INTEGER UNSIGNED DEFAULT NULL,
PRIMARY KEY ( PartID ),
FOREIGN KEY ( CompanyID ) REFERENCES Company,
FOREIGN KEY ( DeviceID ) REFERENCES Device,
UNIQUE ( CompanyID, PartNumber )
);
-- Create a table for packages.
--
-- A package represents the physical form-factor of an electronic device.
--
-- PackageID Surrogate key.
-- PackageName A unique name for the package.
-- SMT TRUE indicates the package uses surface mount technology.
--
CREATE TABLE Package (
PackageID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
PackageName VARCHAR(500) NOT NULL,
Technology VARCHAR(500) NOT NULL,
PRIMARY KEY ( PackageID ),
UNIQUE ( PackageName )
);
-- Create a table for schematic symbols.
--
-- The xpath field stores the location of the symbol file relataive to the
-- gEDA top level directory.
--
CREATE TABLE Symbol (
SymbolID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
SymbolPath VARCHAR(500) NOT NULL,
DeviceID INTEGER UNSIGNED NOT NULL,
PRIMARY KEY ( SymbolID ),
FOREIGN KEY ( DeviceID ) REFERENCES Device,
UNIQUE ( SymbolPath )
);
-- Create a table for symbol details (comments).
--
-- Each symbol may have many comments.
--
CREATE TABLE SymbolDetail (
SymbolID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Detail VARCHAR(500) NOT NULL,
FOREIGN KEY ( SymbolID ) REFERENCES Symbol,
UNIQUE ( SymbolID, Detail )
);
-- Create a view for categories
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW CategoryV AS
SELECT
CategoryID,
CategoryName,
ViewName,
ParentID
FROM Category
ORDER BY CategoryName;
-- Create a view for companies
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW CompanyV AS
SELECT
CompanyName
FROM Company
ORDER BY CompanyName;
-- Create a view for devices
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW DeviceV AS
SELECT
DeviceName
FROM Device
ORDER BY DeviceName;
-- Create a view for documents
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW DocumentV AS
SELECT
Category,
Title,
FileLocation
FROM Document
ORDER BY Category, Title;
-- Create a view for PCB footprints
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW FootprintV AS
SELECT
FootprintName
FROM Footprint
ORDER BY FootprintName;
-- Create a view for component packages
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW PackageV AS
SELECT
PackageName,
Technology AS 'Tech'
FROM Package
ORDER BY PackageName;
-- Create a view for symbols
--
-- This view abstracts the application from the underlying tables.
--
CREATE VIEW SymbolV AS
SELECT
SymbolID,
SymbolPath,
DeviceID,
DeviceName
FROM Symbol
JOIN Device USING ( DeviceID )
ORDER BY SymbolPath;
DELIMITER $$
-- Add a part category to the database
--
-- CategoryName - The name of the new category.
-- ViewName - The name of the view to query for this category
-- ParentName - The name of the parent category. If at the root, NULL.
--
CREATE PROCEDURE AddCategory(
IN CategoryName VARCHAR(500),
IN ViewName VARCHAR(500),
IN ParentName VARCHAR(500)
)
BEGIN
DECLARE ParentID INTEGER UNSIGNED;
SELECT CategoryID INTO ParentID FROM Category WHERE ( Category.CategoryName = ParentName );
INSERT INTO Category (
CategoryName,
ViewName,
ParentID
)
VALUES (
CategoryName,
ViewName,
ParentID
);
END$$
-- Add a company to the database.
--
-- CompanyName - The name of the company to add to the database.
--
CREATE PROCEDURE AddCompany(
IN CompanyName VARCHAR(500)
)
BEGIN
INSERT INTO Company(
CompanyName
)
VALUES (
CompanyName
);
END$$
-- Add a new device to the database.
--
-- DeviceName - The name of the new device to add to the database.
--
CREATE PROCEDURE AddDevice(
IN DeviceName VARCHAR(500)
)
BEGIN
INSERT INTO Device(
DeviceName
)
VALUES (
DeviceName
);
END$$
-- Add a PCB footprint to the database.
--
-- FootprintName - The name of the new footprint to add to the database.
--
--
CREATE PROCEDURE AddFootprint(
IN FootprintName VARCHAR(500)
)
BEGIN
INSERT INTO Footprint(
FootprintName
)
VALUES (
FootprintName
);
END$$
-- Add a package to the database.
--
-- TODO Switch SMT/BOOLEAN to Technology/VARCHAR which could be values 'SMT' or 'TH'
--
CREATE PROCEDURE AddPackage(
IN PackageName VARCHAR(500),
IN Technology VARCHAR(500)
)
BEGIN
INSERT INTO Package (
PackageName,
Technology
)
VALUES (
PackageName,
Technology
);
END$$
-- Add a part to the database.
--
-- CompanyName - The name of the company that manufactures the part
-- PartNumber - The manufacturer's part number
-- DeviceName - The name of the device to associate the part with symbols.
--
CREATE PROCEDURE AddPart(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN DeviceName VARCHAR(500)
)
BEGIN
INSERT INTO Part (
CompanyID,
PartNumber,
DeviceID
)
VALUES (
( SELECT CompanyID FROM Company WHERE Company.CompanyName = CompanyName ),
PartNumber,
( SELECT DeviceID FROM Device WHERE Device.DeviceName = DeviceName )
);
END$$
-- Add a symbol to the database.
--
-- DeviceName - The name of the device
-- SymbolPath - The filesystem path to the symbol.
--
-- The symbol path must uniquely identify the symbol
--
-- TODO Define the path: relative, absolute, URI?
--
CREATE PROCEDURE AddSymbol(
IN DeviceName VARCHAR(500),
IN SymbolPath VARCHAR(500)
)
BEGIN
INSERT INTO Symbol (
DeviceID,
SymbolPath
)
VALUES (
( SELECT DeviceID FROM Device WHERE Device.DeviceName = DeviceName ),
SymbolPath
);
END$$
-- Add a symbol detail (comment) to the database.
--
-- SymbolPath - The name of the symbol
-- Detail - The text of the detail (comment).
--
CREATE PROCEDURE AddSymbolDetail(
IN SymbolPath VARCHAR(500),
IN Detail VARCHAR(500)
)
BEGIN
INSERT INTO SymbolDetail (
SymbolID,
Detail
)
VALUES (
( SELECT SymbolID FROM Symbol WHERE Symbol.SymbolPath = SymbolPath ),
Detail
);
END$$
DELIMITER ;

View File

@ -0,0 +1,77 @@
-- ---------------------------------------------------------------------------
--
-- gEDA - GPL Electronic Design Automation
-- gparts - gEDA Parts Manager
-- Copyright (C) 2009 Edward C. Hennessy
-- Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
--
-- ---------------------------------------------------------------------------
CALL AddCategory(
"Discretes",
NULL,
"UNKNOWN"
);
CALL AddCategory(
"Diodes",
NULL,
"Discretes"
);
CALL AddCategory(
"Small-signal",
"DiodeV",
"Diodes"
);
CALL AddCategory(
"TVS",
"TVSDiodeV",
"Diodes"
);
CALL AddCategory(
"Zeners",
"ZenerDiodeV",
"Diodes"
);
CALL AddCategory(
"Passives",
NULL,
"UNKNOWN"
);
CALL AddCategory(
"Capacitors",
"CapacitorV",
"Passives"
);
CALL AddCategory(
"Inductors",
"InductorV",
"Passives"
);
CALL AddCategory(
"Resistors",
"ResistorV",
"Passives"
);

View File

@ -0,0 +1,239 @@
-- ---------------------------------------------------------------------------
--
-- gEDA - GPL Electronic Design Automation
-- gparts - gEDA Parts Manager
-- Copyright (C) 2009 Edward C. Hennessy
-- Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
--
-- ---------------------------------------------------------------------------
--
-- Create additional tables for storing discrete semiconductors.
--
-- These tables store additional information to allow quick selection of
-- discrete semiconductor components.
--
-- Create a table for diodes.
--
-- This table can be used for most diodes, including small-signal, small-signal
-- Schottky, rectifiers and Schottky rectifiers.
--
-- TODO Should this table include additional fields to indicate the diode type?
-- (e.g. Small-signal, Rectifier, Schottky, etc...)
--
CREATE TABLE Diode (
PartID INTEGER UNSIGNED NOT NULL,
PackageID INTEGER UNSIGNED NOT NULL,
MaxReverseVoltage FLOAT,
TypForwardVoltage FLOAT,
AveForwardCurrent FLOAT,
PRIMARY KEY ( PartID )
);
-- Create a table for TVS diodes.
--
-- TODO What is the best way to indicate bidirectional or unidirectional? The
-- type may be apparent from the symbol. Then, an additional field would not
-- be required.
--
CREATE TABLE TVSDiode (
PartID INTEGER UNSIGNED NOT NULL,
PackageID INTEGER UNSIGNED NOT NULL,
WorkingVoltage FLOAT NOT NULL,
BreakdownVoltage FLOAT NOT NULL,
PRIMARY KEY ( PartID )
);
-- Create a table for zener diodes.
--
CREATE TABLE ZenerDiode (
PartID INTEGER UNSIGNED NOT NULL,
PackageID INTEGER UNSIGNED NOT NULL,
ZenerVoltage FLOAT NOT NULL,
PRIMARY KEY ( PartID )
);
-- Create a view for diodes.
--
CREATE VIEW DiodeV AS
SELECT
Part.PartID,
Company.CompanyName,
Part.PartNumber,
Package.PackageName,
Diode.MaxReverseVoltage AS 'VR',
Diode.TypForwardVoltage AS 'VF',
Diode.AveForwardCurrent AS 'IF',
Device.DeviceID
FROM Diode
JOIN Part USING ( PartID )
JOIN Package USING ( PackageID )
JOIN Company USING ( CompanyID )
JOIN Device USING ( DeviceID );
INSERT INTO ColumnMeta ( ViewName, ColumnName, Units ) VALUES
( 'DiodeV', 'VR', 'VOLTS' ),
( 'DiodeV', 'VF', 'VOLTS' ),
( 'DiodeV', 'IF', 'AMPS' );
-- Create a view for TVS diodes.
--
CREATE VIEW TVSDiodeV AS
SELECT
Part.PartID,
Company.CompanyName,
Part.PartNumber,
TVSDiode.WorkingVoltage AS 'VRWM',
TVSDiode.BreakdownVoltage AS 'VBR'
FROM TVSDiode
JOIN Part USING ( PartID )
JOIN Company USING ( CompanyID );
INSERT INTO ColumnMeta ( ViewName, ColumnName, Units ) VALUES
( 'TVSDiodeV', 'VRWM', 'VOLTS' ),
( 'TVSDiodeV', 'VBR', 'VOLTS' );
-- Create a view for zener diodes.
--
CREATE VIEW ZenerDiodeV AS
SELECT
Part.PartID,
Company.CompanyName,
Part.PartNumber,
Package.PackageName,
ZenerDiode.ZenerVoltage AS 'VZ',
Device.DeviceID,
Device.DeviceName
FROM ZenerDiode
JOIN Part USING ( PartID )
JOIN Package USING ( PackageID )
JOIN Company USING ( CompanyID )
JOIN Device USING ( DeviceID );
INSERT INTO ColumnMeta ( ViewName, ColumnName, Units ) VALUES
( 'ZenerDiodeV', 'VZ', 'VOLTS' );
DELIMITER $$
-- Adds a diode to the GParts database.
--
CREATE PROCEDURE AddDiode(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN PackageName VARCHAR(500),
IN DeviceName VARCHAR(500),
IN MaxReverseVoltage FLOAT,
IN TypForwardVoltage FLOAT,
IN AveForwardCurrent FLOAT
)
BEGIN
CALL AddPart(
CompanyName,
PartNumber,
DeviceName
);
INSERT INTO Diode (
PartID,
Diode.PackageID,
MaxReverseVoltage,
TypForwardVoltage,
AveForwardCurrent
)
VALUES (
( SELECT PartID
FROM Part JOIN Company USING ( CompanyID )
WHERE Company.CompanyName = CompanyName AND Part.PartNumber = PartNumber
),
( SELECT Package.PackageID FROM Package WHERE PackageName = Package.PackageName ),
MaxReverseVoltage,
TypForwardVoltage,
AveForwardCurrent
);
END$$
-- Adds a TVS diode to the GParts database.
--
CREATE PROCEDURE AddTVSDiode(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN PackageName VARCHAR(500),
IN DeviceName VARCHAR(500),
IN WorkingVoltage FLOAT,
IN BreakdownVoltage FLOAT
)
BEGIN
CALL AddPart(
CompanyName,
PartNumber,
DeviceName
);
INSERT INTO TVSDiode (
PartID,
TVSDoide.PackageID,
WorkingVoltage,
BreakdownVoltage
)
VALUES (
( SELECT PartID
FROM Part JOIN Company USING ( CompanyID )
WHERE Company.CompanyName = CompanyName AND Part.PartNumber = PartNumber
),
( SELECT Package.PackageID FROM Package WHERE PackageName = Package.PackageName ),
WorkingVoltage,
BreakdownVoltage
);
END$$
-- Adds a zener diode to the GParts database.
--
CREATE PROCEDURE AddZenerDiode(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN PackageName VARCHAR(500),
IN DeviceName VARCHAR(500),
IN ZenerVoltage FLOAT
)
BEGIN
CALL AddPart(
CompanyName,
PartNumber,
DeviceName
);
INSERT INTO ZenerDiode ( PartID, ZenerDiode.PackageID, ZenerVoltage ) VALUES (
( SELECT PartID
FROM Part JOIN Company USING ( CompanyID )
WHERE Company.CompanyName = CompanyName AND Part.PartNumber = PartNumber
),
( SELECT Package.PackageID FROM Package WHERE PackageName = Package.PackageName ),
ZenerVoltage
);
END$$
DELIMITER ;

View File

@ -0,0 +1,219 @@
-- ---------------------------------------------------------------------------
--
-- gEDA - GPL Electronic Design Automation
-- gparts - gEDA Parts Manager
-- Copyright (C) 2009 Edward C. Hennessy
-- Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
--
-- ---------------------------------------------------------------------------
--
-- Create additional tables for storing passive devices.
--
-- These tables store additional information to allow quick selection of
-- passive electronic components.
--
-- Create a table for capacitors.
--
-- TODO The capacitor table requires more fields to be of any use. For
-- example, the capacitor type: ceramic, aluminum electrolytic, tantalum,
-- etc... Also, I seem to need ESR quite a bit.
--
CREATE TABLE Capacitor (
PartID INTEGER UNSIGNED NOT NULL,
PackageID INTEGER UNSIGNED NOT NULL,
Capacitance FLOAT NOT NULL,
PRIMARY KEY ( PartID )
);
-- Create a table for inductors.
--
-- TODO Requires more columns to be useful.
--
CREATE TABLE Inductor (
PartID INTEGER UNSIGNED NOT NULL,
PackageID INTEGER UNSIGNED NOT NULL,
Inductance FLOAT NOT NULL,
PRIMARY KEY ( PartID )
);
-- Create a table for resistors.
--
-- TODO Requires more columns to be useful.
--
CREATE TABLE Resistor (
PartID INTEGER UNSIGNED NOT NULL,
PackageID INTEGER UNSIGNED NOT NULL,
Resistance FLOAT NOT NULL,
Tolerance FLOAT NOT NULL,
PRIMARY KEY ( PartID )
);
-- Create a view for capacitors.
--
CREATE VIEW CapacitorV AS
SELECT
Company.CompanyName,
Part.PartNumber,
Package.PackageName,
Capacitor.Capacitance,
Part.DeviceID
FROM Capacitor
JOIN Part USING ( PartID )
JOIN Package USING ( PackageID )
JOIN Company USING ( CompanyID );
INSERT INTO ColumnMeta ( ViewName, ColumnName, Units ) VALUES
( 'CapacitorV', 'Capacitance', 'FARADS' );
-- Create a view for inductors.
--
CREATE VIEW InductorV AS
SELECT
Company.CompanyName,
Part.PartNumber,
Package.PackageName,
Inductor.Inductance,
Part.DeviceID
FROM Inductor
JOIN Part USING ( PartID )
Join Package USING ( PackageID )
JOIN Company USING ( CompanyID );
INSERT INTO ColumnMeta ( ViewName, ColumnName, Units ) VALUES
( 'InductorV', 'Inductace', 'HENRYS' );
-- Create a view for resistors.
--
-- For proper formatting, the Resistor.Resistance field must be immediately
-- followed by the Resistor.Tolerance field.
--
CREATE VIEW ResistorV AS
SELECT
Company.CompanyName,
Part.PartNumber,
Package.PackageName,
Resistor.Resistance,
Resistor.Tolerance,
Part.DeviceID
FROM Resistor
JOIN Part USING ( PartID )
Join Package USING ( PackageID )
JOIN Company USING ( CompanyID )
ORDER BY Package.PackageName, Resistor.Resistance;
INSERT INTO ColumnMeta ( ViewName, ColumnName, Units ) VALUES
( 'ResistorV', 'Resistnace', 'OHMS' ),
( 'ResistorV', 'Tolerance', 'PERCENT' );
-- Add a capacitor to the GParts database
--
DELIMITER $$
CREATE PROCEDURE AddCapacitor(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN PackageName VARCHAR(500),
IN DeviceName VARCHAR(500),
IN Capacitance FLOAT
)
BEGIN
CALL AddPart(
CompanyName,
PartNumber,
DeviceName
);
INSERT INTO Capacitor ( PartID, PackageID, Capacitance ) VALUES (
( SELECT PartID
FROM Part JOIN Company USING ( CompanyID )
WHERE Company.CompanyName = CompanyName AND Part.PartNumber = PartNumber
),
( SELECT PackageID FROM Package WHERE PackageName = Package.PackageName ),
Capacitance
);
END$$
-- Add an inductor to the GParts database.
--
CREATE PROCEDURE AddInductor(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN PackageName VARCHAR(500),
IN DeviceName VARCHAR(500),
IN Inductance FLOAT
)
BEGIN
CALL AddPart(
CompanyName,
PartNumber,
DeviceName
);
INSERT INTO Inductor ( PartID, PackageID, Inductance ) VALUES (
( SELECT PartID
FROM Part JOIN Company USING ( CompanyID )
WHERE Company.CompanyName = CompanyName AND Part.PartNumber = PartNumber
),
( SELECT PackageID FROM Package WHERE PackageName = Package.PackageName ),
Inductance
);
END$$
-- Add a resistor to the GParts database.
--
CREATE PROCEDURE AddResistor(
IN CompanyName VARCHAR(500),
IN PartNumber VARCHAR(500),
IN PackageName VARCHAR(500),
IN DeviceName VARCHAR(500),
IN Resistance FLOAT,
IN Tolerance FLOAT
)
BEGIN
CALL AddPart(
CompanyName,
PartNumber,
DeviceName
);
INSERT INTO Resistor ( PartID, Resistor.PackageID, Resistance, Tolerance ) VALUES (
( SELECT PartID
FROM Part JOIN Company USING ( CompanyID )
WHERE Company.CompanyName = CompanyName AND Part.PartNumber = PartNumber
),
( SELECT Package.PackageID FROM Package WHERE PackageName = Package.PackageName ),
Resistance,
Tolerance
);
END$$
DELIMITER ;

1356
src/Doxyfile Executable file

File diff suppressed because it is too large Load Diff

68
src/Makefile.am Normal file
View File

@ -0,0 +1,68 @@
#
#
#
bin_PROGRAMS = gparts
gparts_SOURCES = \
gparts-category-model.c \
gparts-category-controller.c \
gparts-controller.c \
gparts-customize-ctrl.c \
gparts-customize-model.c \
gparts-database.c \
gparts-database-result.c \
gparts-database-type.c \
gparts-login-ctrl.c \
gparts-main.c \
gparts-object-list.c \
gparts-preview.c \
gparts-preview-ctrl.c \
gparts-result-model.c \
gparts-result-controller.c \
gparts-result-view.c \
gparts-state.c \
gparts-units.c
gparts_CFLAGS = $(AM_CFLAGS) $(GMODULE_CFLAGS) $(GTK_CFLAGS)
gparts_LDADD = $(GMODULE_LIBS) $(GTK_LIBS)
#gparts_DEPENDENCIES = $(MYSQL_LDADD) $(POSTGRESQL_LDADD) $(SQLITE_LDADD)
# TODO libraries in EXTRA_LTLIBRARIES do not seem to work with g_module_open (no .so?)
# Libraries in lib_LTLIBRARIES must be built. If conditionally not there, then the
# tool complains about the *_SOURCES, etc...
# The database support modules must be both dynamically loadable and conditionally
# build.
lib_LTLIBRARIES = \
libgparts-mysql.la
EXTRA_LTLIBRARIES = \
libgparts-postgresql.la \
libgparts-sqlite.la
# A dynamically loadable library providing MySQL support.
libgparts_mysql_la_SOURCES = \
gparts-mysql-database.c \
gparts-mysql-module.c \
gparts-mysql-result.c
libgparts_mysql_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(MYSQL_CFLAGS)
libgparts_mysql_la_LIBADD = $(MYSQL_LIBS)
# A dynamically loadable library providing PostgreSQL support.
libgparts_postgresql_la_SOURCES = \
gparts-postgresql-database.c \
gparts-postgresql-module.c \
gparts-postgresql-result.c
libgparts_postgresql_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(POSTGRESQL_CFLAGS)
libgparts_postgresql_la_LIBADD = $(POSTGRESQL_LIBS)
# A dynamically loadable library providing SQLite support.
libgparts_sqlite_la_SOURCES = \
gparts-sqlite-database.c \
gparts-sqlite-module.c \
gparts-sqlite-result.c
libgparts_sqlite_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(SQLITE_CFLAGS)
libgparts_sqlite_la_LIBADD = $(SQLITE_LIBS)

View File

@ -0,0 +1,369 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <string.h>
#include <gtk/gtk.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-category-model.h"
#include "gparts-controller.h"
#include "gparts-category-controller.h"
#include "gparts-login-ctrl.h"
enum
{
GPARTS_CATEGORY_CONTROLLER_PROPID_DATABASE_CONTROLLER = 1,
GPARTS_CATEGORY_CONTROLLER_PROPID_TARGET
};
typedef struct _GPartsCategoryControllerPrivate GPartsCategoryControllerPrivate;
struct _GPartsCategoryControllerPrivate
{
GPartsLoginCtrl *database_controller;
GtkTreeSelection *selection;
GtkTreeView *target;
};
#define GPARTS_CATEGORY_CONTROLLER_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_CATEGORY_CONTROLLER,GPartsCategoryControllerPrivate)
/**** Private functions ****/
static void
gparts_category_controller_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_category_controller_controller_init(GPartsControllerInterface *iface);
static void
gparts_category_controller_dispose(GObject *object);
static gchar*
gparts_category_controller_get_field(GPartsCategoryController *controller, const gchar *name);
static void
gparts_category_controller_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_category_controller_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_category_controller_update(GPartsCategoryController *controller);
/**** Signal handlers ****/
static void
gparts_category_controller_changed_cb(GtkTreeSelection *selection, GPartsCategoryController *controller);
static void
gparts_category_controller_database_controller_notify_cb(GPartsLoginCtrl *database, GParamSpec *pspec, GPartsCategoryController *controller);
/* TODO Support this function */
static void
gparts_category_controller_show_cb(GtkWidget *widget, GPartsCategoryController *controller);
static void
gparts_category_controller_changed_cb(GtkTreeSelection *selection, GPartsCategoryController *controller)
{
g_signal_emit_by_name(controller, "updated");
}
static void
gparts_category_controller_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsCategoryControllerPrivate));
object_class->dispose = gparts_category_controller_dispose;
object_class->get_property = gparts_category_controller_get_property;
object_class->set_property = gparts_category_controller_set_property;
g_object_class_install_property(
object_class,
GPARTS_CATEGORY_CONTROLLER_PROPID_DATABASE_CONTROLLER,
g_param_spec_object(
"database-controller",
"",
"",
GPARTS_TYPE_LOGIN_CTRL,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_CATEGORY_CONTROLLER_PROPID_TARGET,
g_param_spec_object(
"target",
"",
"",
GTK_TYPE_TREE_VIEW,
G_PARAM_READWRITE
)
);
g_signal_new(
"updated",
G_TYPE_FROM_CLASS(object_class),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0
);
}
static void
gparts_category_controller_controller_init(GPartsControllerInterface *iface)
{
iface->get_field = gparts_category_controller_get_field;
}
static void
gparts_category_controller_database_controller_notify_cb(GPartsLoginCtrl *database, GParamSpec *pspec, GPartsCategoryController *controller)
{
gparts_category_controller_update(controller);
}
static void
gparts_category_controller_dispose(GObject *object)
{
GPartsCategoryController *controller = GPARTS_CATEGORY_CONTROLLER(object);
gparts_category_controller_set_database_controller(controller, NULL);
gparts_category_controller_set_target(controller, NULL);
}
static gchar*
gparts_category_controller_get_field(GPartsCategoryController *controller, const gchar *name)
{
GtkTreeIter iter;
GtkTreeModel *model;
GPartsCategoryControllerPrivate *privat = GPARTS_CATEGORY_CONTROLLER_GET_PRIVATE(controller);
gboolean success;
gchar *value = NULL;
g_debug("get field");
success = gtk_tree_selection_get_selected(privat->selection, &model, &iter);
if (success && GPARTS_IS_CATEGORY_MODEL(model))
{
value = gparts_category_model_get_field(GPARTS_CATEGORY_MODEL(model), &iter, name);
}
g_debug("get field 2");
return value;
}
GType
gparts_category_controller_get_type(void)
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsCategoryControllerClass),
NULL,
NULL,
gparts_category_controller_class_init,
NULL,
NULL,
sizeof(GPartsCategoryController),
0,
NULL,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_category_controller_controller_init,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-category-controller",
&tinfo,
0
);
g_type_add_interface_static(
type,
GPARTS_TYPE_CONTROLLER,
&iinfo
);
}
return type;
}
static void
gparts_category_controller_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
}
GPartsCategoryController*
gparts_category_controller_new()
{
}
static void
gparts_category_controller_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
GPartsCategoryController *controller = GPARTS_CATEGORY_CONTROLLER(object);
switch (property_id)
{
case GPARTS_CATEGORY_CONTROLLER_PROPID_DATABASE_CONTROLLER:
gparts_category_controller_set_database_controller(controller, g_value_get_object(value));
break;
case GPARTS_CATEGORY_CONTROLLER_PROPID_TARGET:
gparts_category_controller_set_target(controller, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
void
gparts_category_controller_set_database_controller(GPartsCategoryController *controller, GPartsLoginCtrl *database)
{
GPartsCategoryControllerPrivate *privat = GPARTS_CATEGORY_CONTROLLER_GET_PRIVATE(controller);
if (privat->database_controller != database)
{
if (privat->database_controller != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->database_controller,
G_CALLBACK(gparts_category_controller_database_controller_notify_cb),
controller
);
g_object_unref(privat->database_controller);
}
privat->database_controller = database;
if (privat->database_controller != NULL)
{
g_object_ref(privat->database_controller);
g_signal_connect(
privat->database_controller,
"notify::database",
G_CALLBACK(gparts_category_controller_database_controller_notify_cb),
controller
);
}
gparts_category_controller_update(controller);
g_object_notify(controller, "database-controller");
}
}
void
gparts_category_controller_set_target(GPartsCategoryController *controller, GtkTreeView *target)
{
GPartsCategoryControllerPrivate *private = GPARTS_CATEGORY_CONTROLLER_GET_PRIVATE(controller);
if (private->selection != NULL)
{
g_signal_handlers_disconnect_by_func(
private->selection,
G_CALLBACK(gparts_category_controller_changed_cb),
controller
);
g_object_unref(private->selection);
}
if (private->target != NULL)
{
g_object_unref(private->target);
}
private->selection = NULL;
private->target = target;
if (private->target != NULL)
{
g_object_ref(private->target);
private->selection = gtk_tree_view_get_selection(private->target);
if (private->selection != NULL)
{
g_object_ref(private->selection);
g_signal_connect(
private->selection,
"changed",
G_CALLBACK(gparts_category_controller_changed_cb),
controller
);
}
}
gparts_category_controller_update(controller);
}
static void
gparts_category_controller_update(GPartsCategoryController *controller)
{
GPartsCategoryControllerPrivate *privat = GPARTS_CATEGORY_CONTROLLER_GET_PRIVATE(controller);
if (privat->target != NULL)
{
GPartsCategoryModel *model = NULL;
GPartsDatabase *database = NULL;
if (privat->database_controller != NULL)
{
database = gparts_login_ctrl_get_database(privat->database_controller);
}
if (database != NULL)
{
model = gparts_category_model_new(database);
gparts_category_model_set_columns(model, privat->target);
}
gtk_tree_view_set_model(privat->target, GTK_TREE_MODEL(model));
if (model != NULL)
{
g_object_unref(model);
}
}
}

View File

@ -0,0 +1,73 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-category-controller.h
*
* \brief A controller for the specialized category model and its GUI view.
*
* GtkTreeViews do not handle multiple changes well. So, when changes occur
* to the model's data, the controller creates an new model and places it in
* the GUI view. The old model gets disposed.
*/
#define GPARTS_TYPE_CATEGORY_CONTROLLER (gparts_category_controller_get_type())
#define GPARTS_CATEGORY_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_CATEGORY_CONTROLLER,GPartsCategoryController))
#define GPARTS_CATEGORY_CONTROLLER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_CATEGORY_CONTROLLER,GPartsCategoryControllerClass))
#define GPARTS_IS_CATEGORY_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_CATEGORY_CONTROLLER))
#define GPARTS_IS_CATEGORY_CONTROLLER_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_CATEGORY_CONTROLLER))
#define GPARTS_CATEGORY_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_CATEGORY_CONTROLLER,GPartsCategoryControllerClass))
typedef struct _GPartsCategoryController GPartsCategoryController;
typedef struct _GPartsCategoryControllerClass GPartsCategoryControllerClass;
struct _GPartsCategoryController
{
GObject parent;
};
struct _GPartsCategoryControllerClass
{
GObjectClass parent;
};
GType
gparts_category_controller_get_type(void);
GPartsCategoryController*
gparts_category_controller_new();
/*! \brief Sets the database.
*
* Sets the database to use for subsequent database operations.
*
* \param [in] controller The controller.
* \param [in] database The database to use for subsequent operations.
*/
void
gparts_category_controller_set_database(GPartsCategoryController *query, GPartsDatabase *database);
/*! \brief Sets the target view for results from database queries.
*
* \param [in] controller The controller.
* \param [in] target A GtkTreeView to place database query results into.
*/
void
gparts_category_controller_set_target(GPartsCategoryController *query, GtkTreeView *target);

844
src/gparts-category-model.c Normal file
View File

@ -0,0 +1,844 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-category-model.c
*
* \brief Provides a GtkTreeModel for the category view.
*
* Unlike most of the views in GParts, the category view organizes data
* in a tree structure.
*/
#include <gtk/gtk.h>
#include <string.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-category-model.h"
enum
{
GPARTS_CATEGORY_MODEL_PROPID_DATABASE = 1
};
typedef struct _GPartsCategoryModelPrivate GPartsCategoryModelPrivate;
typedef struct _GPartsCategoryModelNode GPartsCategoryModelNode;
struct _GPartsCategoryModelNode
{
GtkTreeIter parent;
GPartsDatabaseResult *result;
struct _GPartsCategoryModelNode **children;
};
struct _GPartsCategoryModelPrivate
{
GPartsDatabase *database;
GPartsCategoryModelNode *root;
gint stamp;
};
#define GPARTS_CATEGORY_MODEL_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object, GPARTS_TYPE_CATEGORY_MODEL, GPartsCategoryModelPrivate)
static void
gparts_category_model_instance_init(GTypeInstance* instance, gpointer g_class);
static void
gparts_category_model_dispose(GObject* object);
static void
gparts_category_model_finalize(GObject* object);
static void
gparts_category_model_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec);
static void
gparts_category_model_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec);
static void
gparts_load_children(GPartsDatabase* database, GtkTreeIter* iter);
static void
gparts_category_model_tree_model_init(GtkTreeModelIface *iface);
static void
gparts_category_model_set_database(GObject *object, const GValue *value);
static gboolean
gparts_category_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n);
/**
*
*
*
*
*/
static void
gparts_load_root(GPartsDatabase* database, GPartsCategoryModelNode **node)
{
*node = g_new0(GPartsCategoryModelNode, 1);
gchar* query = "SELECT * FROM Category WHERE ParentID IS NULL";
(*node)->result = gparts_database_query(database, query, NULL);
if ((*node)->result != NULL)
{
gint rows = gparts_database_result_get_row_count((*node)->result);
if (rows > 0)
{
(*node)->children = g_new0(GPartsCategoryModelNode, rows);
}
}
}
/*!
*
*
*
*/
static void
gparts_category_model_load_children(GPartsDatabase* database, GtkTreeIter *iter)
{
GPartsCategoryModelNode **child;
gint index;
GPartsCategoryModelNode *node;
node = (GPartsCategoryModelNode*) iter->user_data;
index = GPOINTER_TO_INT(iter->user_data2);
child = node->children + index;
if (*child == NULL)
{
GValue value0 = {0};
GValue value1 = {0};
*child = g_new0(GPartsCategoryModelNode, 1);
(*child)->parent = *iter;
gparts_database_result_get_field_value(node->result, index, 0, &value0);
g_value_init(&value1, G_TYPE_STRING);
g_value_transform(&value0, &value1);
g_value_unset(&value0);
GString *query = g_string_new(NULL);
g_string_printf(query, "SELECT * FROM Category WHERE ParentID = %s", g_value_get_string(&value1));
g_value_unset(&value1);
(*child)->result = gparts_database_query(database, query->str, NULL);
g_string_free(query, TRUE);
(*child)->children = g_new0(GPartsCategoryModelNode, gparts_database_result_get_row_count((*child)->result));
}
}
/*! \brief
*
*
*
*/
static void
gparts_category_model_database_connected_cb(GPartsDatabase *database)
{
}
/*! \brief
*
*
*
*
*
*/
static void
gparts_category_model_database_disconnected_cb(GPartsDatabase *database)
{
}
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_category_model_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(
g_class,
sizeof( GPartsCategoryModelPrivate )
);
object_class->dispose = gparts_category_model_dispose;
object_class->finalize = gparts_category_model_finalize;
object_class->get_property = gparts_category_model_get_property;
object_class->set_property = gparts_category_model_set_property;
g_object_class_install_property(
object_class,
GPARTS_CATEGORY_MODEL_PROPID_DATABASE,
g_param_spec_object(
"database",
"",
"",
G_TYPE_OBJECT, /* \todo See if this can be an interface */
G_PARAM_READWRITE
)
);
}
/** \brief Unreference all referenced objects.
*
* This function provides the first stage of object destruction.
*
* \param [in] object The object to dispose.
*/
static void
gparts_category_model_dispose(GObject *object)
{
GPartsCategoryModelPrivate *private;
private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(object);
gparts_category_model_set_database(object, NULL);
/*\todo Do the signal handlers for the tree store need to be disconnected? */
// g_object_unref(private->tree_store);
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_category_model_finalize(GObject *object)
{
}
gchar*
gparts_category_model_get_field(GPartsCategoryModel* model, GtkTreeIter *iter, const gchar *name)
{
GPartsCategoryModelNode *node = (GPartsCategoryModelNode*) iter->user_data;
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(model);
gchar *result = NULL;
if (node->result != NULL)
{
gint index;
gboolean success;
success = gparts_database_result_get_column_index(node->result, name, &index);
if (success)
{
gboolean error = FALSE;
GString *buffer = g_string_sized_new(10);
GValue value = {0};
gparts_database_result_get_field_value(
node->result,
GPOINTER_TO_UINT(iter->user_data2),
index,
&value
);
/* TODO The following code needs to go elsewhere or use transformations */
if(G_IS_VALUE(&value))
{
if (G_VALUE_HOLDS_STRING(&value))
{
g_string_printf(buffer, "%s", g_value_get_string(&value));
}
else if (G_VALUE_HOLDS_DOUBLE(&value))
{
g_string_printf(buffer, "%f", g_value_get_double(&value));
}
else if (G_VALUE_HOLDS_INT(&value))
{
g_string_printf(buffer, "%d", g_value_get_int(&value));
}
else
{
error = TRUE;
}
result = g_string_free(buffer, error);
}
}
}
return result;
}
/*! \brief
*
*
*
*
*/
static void
gparts_category_model_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsCategoryModelPrivate *private;
private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(object);
/* \todo handle case where private is NULL */
switch ( property_id )
{
case GPARTS_CATEGORY_MODEL_PROPID_DATABASE:
g_value_set_object(value, private->database);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief
*
*
*
*
*/
GType
gparts_category_model_get_type( void )
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsCategoryModelClass),
NULL,
NULL,
gparts_category_model_class_init,
NULL,
NULL,
sizeof(GPartsCategoryModel),
0,
gparts_category_model_instance_init,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_category_model_tree_model_init,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-category-model",
&tinfo,
0
);
g_type_add_interface_static(
type,
GTK_TYPE_TREE_MODEL,
&iinfo
);
}
return type;
}
/*! \brief Initialize instance data.
*
* \param instance
* \param g_class
*/
static void
gparts_category_model_instance_init(GTypeInstance* instance, gpointer g_class)
{
GPartsCategoryModelPrivate *private;
private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(instance);
}
GPartsCategoryModel *
gparts_category_model_new(GPartsDatabase *database)
{
return g_object_new(GPARTS_TYPE_CATEGORY_MODEL, "database", database, NULL);
}
/*! \brief
*
*
*
*
*/
static void
gparts_category_model_set_database(GObject *object, const GValue *value)
{
GPartsCategoryModelPrivate *private;
private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(object);
if (private->database != NULL)
{
g_signal_handlers_disconnect_by_func(
private->database,
G_CALLBACK(gparts_category_model_database_connected_cb),
object
);
g_signal_handlers_disconnect_by_func(
private->database,
G_CALLBACK(gparts_category_model_database_disconnected_cb),
object
);
g_object_unref(private->database);
private->database = NULL;
//gtk_tree_store_clear( private->tree_store );
}
/* odo Check for correct type before setting database */
if (TRUE)
{
private->database = g_value_get_object(value);
}
if (private->database != NULL)
{
g_object_ref(private->database);
g_signal_connect(
private->database,
"database-connected",
G_CALLBACK(gparts_category_model_database_connected_cb),
object
);
g_signal_connect(
private->database,
"database-disconnected",
G_CALLBACK(gparts_category_model_database_disconnected_cb),
object
);
gparts_load_root(private->database, &(private->root));
}
}
/*! \brief
*
*
*
*
*/
static void
gparts_category_model_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch ( property_id )
{
case GPARTS_CATEGORY_MODEL_PROPID_DATABASE:
gparts_category_model_set_database(object, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/**
*
*
*
*/
static GType
gparts_category_model_get_column_type(GtkTreeModel *tree_model, gint index)
{
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
return gparts_database_result_get_column_type(private->root->result, index);
}
/**
*
*
*
*/
static gboolean
gparts_category_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
{
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
gint c =0;
gint d = gtk_tree_path_get_depth(path);
gint index = gtk_tree_path_get_indices(path)[c++];
GtkTreeIter pos;
gboolean success = gparts_category_model_iter_nth_child(tree_model, &pos, NULL, index);
if (!success) return FALSE;
while (c<d)
{
GtkTreeIter zippy;
zippy = pos;
index = gtk_tree_path_get_indices(path)[c++];
gboolean success = gparts_category_model_iter_nth_child(tree_model, &pos, &zippy, index);
if (!success) return FALSE;
}
*iter = pos;
return TRUE;
}
/**
*
*
*
*/
static GtkTreeModelFlags
gparts_category_model_get_flags(GtkTreeModel *tree_model)
{
return 0; //GTK_TREE_MODEL_LIST_ONLY; //FIXME temp
}
/** @brief Returns the number of columns in the treemodel
*
*
*
*/
static gint
gparts_category_model_get_n_columns(GtkTreeModel *tree_model)
{
gint columns = 0;
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
if (private->root->result != NULL)
{
columns = gparts_database_result_get_column_count(private->root->result);
}
return columns;
}
/**
*
*
*
*/
static GtkTreePath*
gparts_category_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
g_debug("gparts_category_model_get_path");
g_assert(FALSE);
}
/*! \brief Retrieve a value from the tree model.
*
*
*
*/
static void
gparts_category_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
{
GPartsCategoryModelNode *node = (GPartsCategoryModelNode*) iter->user_data;
gparts_database_result_get_field_value(
node->result,
GPOINTER_TO_UINT(iter->user_data2),
column,
value
);
/* \todo Find a better way to handle NULLs from the database */
if (!G_IS_VALUE(value))
{
g_value_init(value, G_TYPE_STRING);
g_value_set_static_string(value, "NULL");
}
}
/*!
*
*
*
*/
static gboolean
gparts_category_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
{
gparts_category_model_iter_nth_child(tree_model, iter, parent, 0);
}
/**
*
*
*
*/
static gboolean
gparts_category_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
gparts_category_model_load_children(private->database, iter);
GPartsCategoryModelNode *node = (GPartsCategoryModelNode*) iter->user_data;
gint index = GPOINTER_TO_INT(iter->user_data2);
GPartsCategoryModelNode **child = node->children + index;
if ((*child)->result != NULL)
{
if ( gparts_database_result_get_row_count((*child)->result) > 0 )
return TRUE;
}
return FALSE;
}
/*!
*
*
*
*/
static gboolean
gparts_category_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
guint new_position;
guint old_position;
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == private->stamp);
old_position = GPOINTER_TO_UINT(iter->user_data2);
new_position = old_position + 1;
if (new_position > old_position)
{
GPartsCategoryModelNode *node = (GPartsCategoryModelNode*) iter->user_data;
gint rows = gparts_database_result_get_row_count(node->result);
if (new_position < rows)
{
iter->user_data2 = GUINT_TO_POINTER(new_position);
return TRUE;
}
}
memset(iter, 0, sizeof(*iter));
return FALSE;
}
/*! \brief Gets an iterator for the nth child of the parent node.
*
* \param [in] tree_model The GtkTreeModel.
* \param [out] iter The iterator to the nth child of parent.
* \param [in] parent An iterator referencing the parent node.
* \param [in] n Zero based index of the child of the parent to get.
* \return TRUE if successful and iter is valid. FALSE if otherwise.
*/
static gboolean
gparts_category_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
{
GPartsCategoryModelNode *list;
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
if (parent == NULL)
{
list = private->root;
}
else
{
g_assert(parent->stamp == private->stamp);
GPartsCategoryModelNode *parent_list = (GPartsCategoryModelNode*) parent->user_data;
g_assert(parent_list != NULL);
g_assert(parent_list->result != NULL);
gint offset = GPOINTER_TO_INT(parent->user_data2);
gint rows = gparts_database_result_get_row_count(parent_list->result);
g_assert(offset < rows);
list = *(parent_list->children + offset);
}
if (list != NULL && list->result != NULL)
{
gint rows = gparts_database_result_get_row_count(list->result);
if (n < rows)
{
iter->stamp = private->stamp;
iter->user_data = list;
iter->user_data2 = GINT_TO_POINTER(n);
return TRUE;
}
}
memset(iter, 0, sizeof(*iter));
return FALSE;
}
/**
*
*
*
*/
static gboolean
gparts_category_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
GPartsCategoryModelPrivate *private;
private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
g_debug("gparts_category_model_iter_n_children");
return FALSE;
// return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(private->tree_store), iter);
}
/*! \brief Gets an iterator for the parent node of a given child node.
*
* \param [in] tree_model The GtkTreeModel.
* \param [out] iter The parent of the child node.
* \param [in] child An iterator referencing the child node.
* \return TRUE successful and iter is valid. FALSE if otherwise.
*/
static gboolean
gparts_category_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
{
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(tree_model);
GPartsCategoryModelNode *node = (GPartsCategoryModelNode*) child->user_data;
if (node->parent.user_data != NULL)
{
*iter = node->parent;
return TRUE;
}
memset(iter, 0, sizeof(*iter));
return FALSE;
}
/*! \brief
*
*
*
*/
static void
gparts_category_model_tree_model_init(GtkTreeModelIface *iface)
{
iface->get_flags = gparts_category_model_get_flags;
iface->get_n_columns = gparts_category_model_get_n_columns;
iface->get_column_type = gparts_category_model_get_column_type;
iface->get_iter = gparts_category_model_get_iter;
iface->get_path = gparts_category_model_get_path;
iface->get_value = gparts_category_model_get_value;
iface->iter_next = gparts_category_model_iter_next;
iface->iter_children = gparts_category_model_iter_children;
iface->iter_has_child = gparts_category_model_iter_has_child;
iface->iter_n_children = gparts_category_model_iter_n_children;
iface->iter_nth_child = gparts_category_model_iter_nth_child;
iface->iter_parent = gparts_category_model_iter_parent;
}
/*! \brief Hides the columns not needed for general use.
*
* Before calling this function, the tree view must be set with the columns
* for a GPartsCategoryModel.
*
* \param [in] tree_view The tree view with the columns to hide.
*/
void
gparts_category_model_hide_columns(GtkTreeView *tree_view)
{
gint index = 0;
GtkTreeViewColumn *column;
column = gtk_tree_view_get_column(tree_view, index++);
while (column != NULL)
{
const gchar *name = gtk_tree_view_column_get_title(column);
gboolean visible = (name != NULL) && (strcmp(name, "CategoryName") == 0);
gtk_tree_view_column_set_visible(column, visible);
column = gtk_tree_view_get_column(tree_view, index++);
}
}
/*! \brief
*
*
*
*/
void
gparts_category_model_set_columns(GPartsCategoryModel* model, GtkTreeView *tree_view)
{
GPartsCategoryModelPrivate *private = GPARTS_CATEGORY_MODEL_GET_PRIVATE(model);
if (private->root->result != NULL)
{
gparts_result_model_set_columns(private->root->result, tree_view);
gparts_category_model_hide_columns(tree_view);
}
}

View File

@ -0,0 +1,70 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-category-model.h
*
* \brief Provides a GtkTreeModel for the category view.
*
* Unlike most of the views in GParts, the category view organizes data
* in a tree structure.
*/
#define GPARTS_TYPE_CATEGORY_MODEL (gparts_category_model_get_type())
#define GPARTS_CATEGORY_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_CATEGORY_MODEL,GPartsCategoryModel))
#define GPARTS_CATEGORY_MODEL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_CATEGORY_MODEL,GPartsCategoryModelClass))
#define GPARTS_IS_CATEGORY_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_CATEGORY_MODEL))
#define GPARTS_IS_CATEGORY_MODEL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_CATEGORY_MODEL))
#define GPARTS_CATEGORY_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_CATEGORY_MODEL,GPartsCategoryModelClass))
typedef struct _GPartsCategoryModel GPartsCategoryModel;
typedef struct _GPartsCategoryModelClass GPartsCategoryModelClass;
struct _GPartsCategoryModel
{
GObject parent;
};
struct _GPartsCategoryModelClass
{
GObjectClass parent;
};
GType
gparts_category_model_get_type( void );
GPartsCategoryModel*
gparts_category_model_new(GPartsDatabase *database);
/*! \brief TODO Finish
*
* \param [in] model The model containing the field.
* \param [in] iter An iterator to the selected row.
* \param [in] name The column name of the field.
* \return The field value as a string. This value must be freed when no
* longer needed.
*/
gchar*
gparts_category_model_get_field(GPartsCategoryModel* model, GtkTreeIter *iter, const gchar *name);
/*! TODO Finish
*/
void
gparts_category_model_set_columns(GPartsCategoryModel* model, GtkTreeView *tree_view);

80
src/gparts-controller.c Normal file
View File

@ -0,0 +1,80 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include "gparts-controller.h"
static void
gparts_controller_base_init(gpointer g_class)
{
}
gchar*
gparts_controller_get_field(GPartsController *controller, const gchar *name)
{
gchar *field = NULL;
GPartsControllerInterface *iface = GPARTS_CONTROLLER_GET_INTERFACE(controller);
if (iface == NULL)
{
}
else if (iface->get_field == NULL)
{
}
else
{
field = iface->get_field(controller, name);
}
return field;
}
GType
gparts_controller_get_type(void)
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo info = {
sizeof(GPartsControllerInterface),
gparts_controller_base_init,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_INTERFACE,
"gparts-controller",
&info,
0
);
}
return type;
}

54
src/gparts-controller.h Normal file
View File

@ -0,0 +1,54 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-controller.h
*
* \brief An interface for GParts' controllers.
*/
#define GPARTS_TYPE_CONTROLLER (gparts_controller_get_type())
#define GPARTS_CONTROLLER(object) (G_TYPE_CHECK_INSTANCE_CAST((object),GPARTS_TYPE_CONTROLLER,GPartsController))
#define GPARTS_IS_CONTROLLER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object),GPARTS_TYPE_CONTROLLER))
#define GPARTS_CONTROLLER_GET_INTERFACE(instance) (G_TYPE_INSTANCE_GET_INTERFACE((instance),GPARTS_TYPE_CONTROLLER,GPartsControllerInterface))
typedef struct _GPartsController GPartsController;
typedef struct _GPartsControllerInterface GPartsControllerInterface;
struct _GPartsControllerInterface
{
GTypeInterface parent;
gchar* (*get_field)(GPartsController *controller, const gchar *name);
};
/*! \brief Gets the value of a field.
*
* \param [in] controller The controller containing the data.
* \param [in] name The name of the field to get.
* \return A NULL terminated string containing the value of the field. The
* caller must free the memory when no longer needed. This function returns
* NULL if it cannot produce a value.
*/
gchar*
gparts_controller_get_field(GPartsController *controller, const gchar *name);
GType
gparts_controller_get_type(void);

482
src/gparts-customize-ctrl.c Normal file
View File

@ -0,0 +1,482 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-customize-ctrl.h"
#include "gparts-customize-model.h"
#define GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_CUSTOMIZE_CTRL,GPartsCustomizeCtrlPrivate)
enum
{
GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_ACTION = 1,
GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_DIALOG,
GPARTS_CUSTOMIZE_CTRL_PROPID_TARGET_VIEW,
};
typedef struct _GPartsCustomizeCtrlPrivate GPartsCustomizeCtrlPrivate;
struct _GPartsCustomizeCtrlPrivate
{
GtkAction *customize_action;
GtkDialog *customize_dialog;
GtkTreeView *target_view;
GtkTreeView *view;
};
static GtkDialog*
gparts_customize_ctrl_build_customize_dialog(GPartsCustomizeCtrl *customize_ctrl);
static void
gparts_customize_ctrl_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_customize_ctrl_dispose(GObject *object);
static void
gparts_customize_ctrl_finalize(GObject *object);
static void
gparts_customize_ctrl_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_customize_ctrl_init(GTypeInstance* instance, gpointer g_class);
static void
gparts_customize_ctrl_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_customize_ctrl_update_action(GPartsCustomizeCtrl *customize_ctrl);
/**** Signal handlers ****/
static void
gparts_customize_ctrl_customize_action_cb(GtkAction *action, GPartsCustomizeCtrl *customize_ctrl);
static void
gparts_customize_ctrl_visible_toggled_cb(GtkCellRendererToggle *toggle, gchar *path, GPartsCustomizeCtrl *customize_ctrl);
static GtkDialog*
gparts_customize_ctrl_build_customize_dialog(GPartsCustomizeCtrl *customize_ctrl)
{
GtkTreeViewColumn *column;
GtkDialog *dialog;
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
GtkCellRendererToggle *toggle;
dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(
"Customize View",
NULL,
GTK_DIALOG_MODAL,
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL
));
gtk_dialog_set_alternative_button_order(
dialog,
GTK_RESPONSE_HELP,
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1
);
gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK);
privat->view = GTK_TREE_VIEW(g_object_new(
GTK_TYPE_TREE_VIEW,
NULL
));
gtk_widget_show(GTK_WIDGET(privat->view));
gtk_tree_selection_set_mode(
gtk_tree_view_get_selection(privat->view),
GTK_SELECTION_NONE
);
gtk_tree_view_set_headers_visible(privat->view, TRUE);
column = gtk_tree_view_column_new_with_attributes(
"Column",
g_object_new(
GTK_TYPE_CELL_RENDERER_TEXT,
"sensitive", FALSE,
NULL
),
"text", 0,
NULL
);
g_object_set(column, "expand", TRUE, NULL);
gtk_tree_view_append_column(privat->view, column);
toggle = g_object_new(
GTK_TYPE_CELL_RENDERER_TOGGLE,
NULL
);
g_signal_connect(
toggle,
"toggled",
G_CALLBACK(gparts_customize_ctrl_visible_toggled_cb),
customize_ctrl
);
gtk_tree_view_insert_column_with_attributes(
privat->view,
-1,
"Visible",
GTK_CELL_RENDERER(toggle),
"active", 1,
NULL
);
gtk_container_add(GTK_CONTAINER(dialog->vbox), GTK_WIDGET(privat->view));
return dialog;
}
static void
gparts_customize_ctrl_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsCustomizeCtrlPrivate));
object_class->dispose = gparts_customize_ctrl_dispose;
object_class->finalize = gparts_customize_ctrl_finalize;
object_class->get_property = gparts_customize_ctrl_get_property;
object_class->set_property = gparts_customize_ctrl_set_property;
g_object_class_install_property(
object_class,
GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_ACTION,
g_param_spec_object(
"customize-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_DIALOG,
g_param_spec_object(
"customize-dialog",
"",
"",
GTK_TYPE_DIALOG,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_CUSTOMIZE_CTRL_PROPID_TARGET_VIEW,
g_param_spec_object(
"target-view",
"",
"",
GTK_TYPE_TREE_VIEW,
G_PARAM_READWRITE
)
);
}
static void
gparts_customize_ctrl_customize_action_cb(GtkAction *action, GPartsCustomizeCtrl *customize_ctrl)
{
GPartsCustomizeModel *model = NULL;
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
gint result;
if (privat->view != NULL)
{
model = g_object_new(GPARTS_TYPE_CUSTOMIZE_MODEL, "view", privat->target_view, NULL);
gtk_tree_view_set_model(privat->view, GTK_TREE_MODEL(model));
}
result = gtk_dialog_run(privat->customize_dialog);
gtk_widget_hide(GTK_WIDGET(privat->customize_dialog));
}
static void
gparts_customize_ctrl_dispose(GObject *object)
{
GPartsCustomizeCtrl *controller = GPARTS_CUSTOMIZE_CTRL(object);
gparts_customize_ctrl_set_customize_action(controller, NULL);
gparts_customize_ctrl_set_customize_dialog(controller, NULL);
gparts_customize_ctrl_set_target_view(controller, NULL);
/* TODO Chain up */
}
static void
gparts_customize_ctrl_finalize(GObject *object)
{
GPartsCustomizeCtrlPrivate *private = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(object);
/* TODO Chain up */
}
static void
gparts_customize_ctrl_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(object);
switch (property_id)
{
case GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_ACTION:
g_value_set_object(value, privat->customize_action);
break;
case GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_DIALOG:
g_value_set_object(value, privat->customize_dialog);
break;
case GPARTS_CUSTOMIZE_CTRL_PROPID_TARGET_VIEW:
g_value_set_object(value, privat->target_view);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
GType
gparts_customize_ctrl_get_type(void)
{
static GType type = G_TYPE_INVALID;
if (type == G_TYPE_INVALID)
{
static const GTypeInfo tinfo = {
sizeof(GPartsCustomizeCtrlClass), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
gparts_customize_ctrl_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof(GPartsCustomizeCtrl), /* instance_size */
0, /* n_preallocs */
gparts_customize_ctrl_init, /* instance_init */
NULL /* value_table */
};
#if 0
static const GInterfaceInfo iinfo = {
gparts_object_list_buildable_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
#endif
type = g_type_register_static(
G_TYPE_OBJECT,
"GPartsCustomizeCtrl",
&tinfo,
0
);
/* g_type_add_interface_static(type, GTK_TYPE_BUILDABLE, &iinfo); */
}
return type;
}
static void
gparts_customize_ctrl_init(GTypeInstance* instance, gpointer g_class)
{
GtkDialog *dialog = gparts_customize_ctrl_build_customize_dialog(GPARTS_CUSTOMIZE_CTRL(instance));
gparts_customize_ctrl_set_customize_dialog(GPARTS_CUSTOMIZE_CTRL(instance), dialog);
g_object_unref(dialog);
}
void
gparts_customize_ctrl_set_customize_action(GPartsCustomizeCtrl *customize_ctrl, GtkAction *action)
{
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
if (privat->customize_action != action)
{
if (privat->customize_action != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->customize_action,
G_CALLBACK(gparts_customize_ctrl_customize_action_cb),
customize_ctrl
);
g_object_unref(privat->customize_action);
}
privat->customize_action = action;
if (privat->customize_action != NULL)
{
g_object_ref(privat->customize_action);
g_signal_connect(
privat->customize_action,
"activate",
G_CALLBACK(gparts_customize_ctrl_customize_action_cb),
customize_ctrl
);
}
g_object_notify(G_OBJECT(customize_ctrl), "customize-action");
gparts_customize_ctrl_update_action(customize_ctrl);
}
}
void
gparts_customize_ctrl_set_customize_dialog(GPartsCustomizeCtrl *customize_ctrl, GtkDialog *dialog)
{
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
if (privat->customize_dialog != dialog)
{
if (privat->customize_dialog != NULL)
{
g_object_unref(privat->customize_dialog);
}
privat->customize_dialog = dialog;
if (privat->customize_dialog != NULL)
{
g_object_ref(privat->customize_dialog);
}
g_object_notify(G_OBJECT(customize_ctrl), "customize-dialog");
}
}
static void
gparts_customize_ctrl_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
GPartsCustomizeCtrl *customize_ctrl = GPARTS_CUSTOMIZE_CTRL(object);
switch (property_id)
{
case GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_ACTION:
gparts_customize_ctrl_set_customize_action(customize_ctrl, g_value_get_object(value));
break;
case GPARTS_CUSTOMIZE_CTRL_PROPID_CUSTOMIZE_DIALOG:
gparts_customize_ctrl_set_customize_dialog(customize_ctrl, g_value_get_object(value));
break;
case GPARTS_CUSTOMIZE_CTRL_PROPID_TARGET_VIEW:
gparts_customize_ctrl_set_target_view(customize_ctrl, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
void
gparts_customize_ctrl_set_target_view(GPartsCustomizeCtrl *customize_ctrl, GtkTreeView *view)
{
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
if (privat->target_view != view)
{
if (privat->target_view != NULL)
{
g_object_unref(privat->target_view);
}
privat->target_view = view;
if (privat->target_view != NULL)
{
g_object_ref(privat->target_view);
}
g_object_notify(G_OBJECT(customize_ctrl), "target-view");
gparts_customize_ctrl_update_action(customize_ctrl);
}
}
static void
gparts_customize_ctrl_update_action(GPartsCustomizeCtrl *customize_ctrl)
{
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
if (privat != NULL && privat->customize_action != NULL)
{
gboolean sensitive = FALSE;
if (privat->target_view != NULL)
{
GtkTreeModel *model = gtk_tree_view_get_model(privat->target_view);
sensitive = (model != NULL);
}
gtk_action_set_sensitive(privat->customize_action, sensitive);
}
}
static void
gparts_customize_ctrl_visible_toggled_cb(GtkCellRendererToggle *toggle, gchar *path, GPartsCustomizeCtrl *customize_ctrl)
{
GPartsCustomizeCtrlPrivate *privat = GPARTS_CUSTOMIZE_CTRL_GET_PRIVATE(customize_ctrl);
if (privat->view != NULL)
{
GtkTreeModel *model = gtk_tree_view_get_model(privat->view);
if (GPARTS_IS_CUSTOMIZE_MODEL(model))
{
gboolean active = gtk_cell_renderer_toggle_get_active(toggle);
GtkTreeIter iter;
GtkTreePath *tpath = gtk_tree_path_new_from_string(path);
if (gtk_tree_model_get_iter(model, &iter, tpath))
{
gparts_customize_model_set_visible(
GPARTS_CUSTOMIZE_MODEL(model),
&iter,
!active
);
}
}
}
}

View File

@ -0,0 +1,70 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-customize-ctrl.h
*/
#define GPARTS_TYPE_CUSTOMIZE_CTRL (gparts_customize_ctrl_get_type())
#define GPARTS_CUSTOMIZE_CTRL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_CUSTOMIZE_CTRL,GPartsCustomizeCtrl))
#define GPARTS_CUSTOMIZE_CTRL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_CUSTOMIZE_CTRL,GPartsCustomizeCtrlClass))
#define GPARTS_IS_CUSTOMIZE_CTRL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_CUSTOMIZE_CTRL))
#define GPARTS_IS_CUSTOMIZE_CTRL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_CUSTOMIZE_CTRL))
#define GPARTS_CUSTOMIZE_CTRL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_CUSTOMIZE_CTRL,GPartsCustomizeCtrlClass))
typedef struct _GPartsCustomizeCtrl GPartsCustomizeCtrl;
typedef struct _GPartsCustomizeCtrlClass GPartsCustomizeCtrlClass;
struct _GPartsCustomizeCtrl
{
GObject parent;
};
struct _GPartsCustomizeCtrlClass
{
GObjectClass parent;
};
GType
gparts_customize_ctrl_get_type(void);
/*! \brief Sets the action to initiate customization.
*
* \param [in] controller The controller.
* \param [in] action The action to initiate customization.
*/
void
gparts_customize_ctrl_set_customize_action(GPartsCustomizeCtrl *customize_ctrl, GtkAction *action);
/*! \brief Sets the dialog for customization.
*
* \param [in] controller The controller.
* \param [in] dialog The dialog to perform customization.
*/
void
gparts_customize_ctrl_set_customize_dialog(GPartsCustomizeCtrl *customize_ctrl, GtkDialog *dialog);
/*! \brief Sets the target view for customization.
*
* \param [in] controller The controller.
* \param [in] target A GtkTreeView to customize.
*/
void
gparts_customize_ctrl_set_target_view(GPartsCustomizeCtrl *customize_ctrl, GtkTreeView *view);

View File

@ -0,0 +1,615 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-customize-model.h"
#define GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_CUSTOMIZE_MODEL,GPartsCustomizeModelPrivate)
enum
{
GPARTS_CUSTOMIZE_MODEL_PROPID_VIEW = 1
};
typedef struct _GPartsCustomizeModelPrivate GPartsCustomizeModelPrivate;
struct _GPartsCustomizeModelPrivate
{
GtkTreeView *view;
gint stamp;
};
static void
gparts_customize_model_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_customize_model_dispose(GObject *object);
static void
gparts_customize_model_finalize(GObject *object);
static GType
gparts_customize_model_get_column_type(GtkTreeModel *tree_model, gint index);
static void
gparts_customize_model_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static GtkTreeModelFlags
gparts_customize_model_get_flags(GtkTreeModel *tree_model);
static gboolean
gparts_customize_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path);
static gint
gparts_customize_model_get_n_columns(GtkTreeModel *tree_model);
static GtkTreePath*
gparts_customize_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter);
static void
gparts_customize_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value);
static void
gparts_customize_model_instance_init(GTypeInstance *instance, gpointer g_class);
/*static*/ gboolean
gparts_customize_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent);
static gboolean
gparts_customize_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter);
static gboolean
gparts_customize_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter);
static gint
gparts_customize_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter);
static gboolean
gparts_customize_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n);
static gboolean
gparts_customize_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child);
static void
gparts_customize_model_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_customize_model_set_view(GObject *object, GtkTreeView *value);
static void
gparts_customize_model_tree_model_init(GtkTreeModelIface *iface);
static void
gparts_customize_model_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsCustomizeModelPrivate));
object_class->dispose = gparts_customize_model_dispose;
object_class->finalize = gparts_customize_model_finalize;
object_class->get_property = gparts_customize_model_get_property;
object_class->set_property = gparts_customize_model_set_property;
g_object_class_install_property(
object_class,
GPARTS_CUSTOMIZE_MODEL_PROPID_VIEW,
g_param_spec_object(
"view",
"",
"",
GTK_TYPE_TREE_VIEW,
G_PARAM_READWRITE
)
);
}
static void
gparts_customize_model_dispose(GObject *object)
{
g_debug("gparts_customize_model_dispose()");
gparts_customize_model_set_view(object, NULL);
GObjectClass *parent_class = g_type_class_peek_parent(GPARTS_CUSTOMIZE_MODEL_GET_CLASS(object));
G_OBJECT_CLASS(parent_class)->dispose(object);
}
static void
gparts_customize_model_finalize(GObject *object)
{
g_debug("gparts_customize_model_finalize()");
GObjectClass *parent_class = g_type_class_peek_parent(GPARTS_CUSTOMIZE_MODEL_GET_CLASS(object));
G_OBJECT_CLASS(parent_class)->finalize(object);
}
/*! \brief Gets the GType of a given column.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [in] index The zero based index of the column.
* \return The column's GType.
*/
static GType
gparts_customize_model_get_column_type(GtkTreeModel *tree_model, gint index)
{
GType type;
switch (index)
{
case 0:
type = G_TYPE_STRING;
break;
case 1:
type = G_TYPE_BOOLEAN;
break;
default:
type = G_TYPE_INVALID;
}
return type;
}
/*! \brief
*
*
*
*
*/
static void
gparts_customize_model_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(object);
/* TODO handle case where private is NULL */
switch (property_id)
{
case GPARTS_CUSTOMIZE_MODEL_PROPID_VIEW:
g_value_set_object(value, privat->view);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief Gets this model's GtkTreeModelFlags.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \return This model's GtkTreeModelFlags.
*/
static GtkTreeModelFlags
gparts_customize_model_get_flags(GtkTreeModel *tree_model)
{
return GTK_TREE_MODEL_LIST_ONLY;
}
/*! \brief Converts a tree path to a tree iterator.
*
* This function will fail if the path does not refer to a valid node in the
* tree model.
*
* \param [in] tree_model The GPartsCustomizeModel
* \param [out] iter If successful, a GtkTreeIter. Invalid if unsuccessful.
* \param [in] path The GtkTreePath to convert to a GtkTreeIter.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_customize_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
gint index = gtk_tree_path_get_indices(path)[0];
guint rows = gparts_customize_model_iter_n_children(tree_model, NULL);
if (index < rows)
{
iter->stamp = privat->stamp;
iter->user_data = GUINT_TO_POINTER(index);
return TRUE;
}
return FALSE;
}
/*! \brief Returns the number of columns in the tree model.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [in] tree_model The given tree model.
* \return The number of columns in the tree model.
*/
static gint
gparts_customize_model_get_n_columns(GtkTreeModel *tree_model)
{
return 2;
}
/*! \brief Converts a GtkTreeIter to a GtkTreePath.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [in] iter The iterator to convert to a tree path.
* \return A GtkTreePath that refers to the same node as the iterator.
*/
static GtkTreePath*
gparts_customize_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
GPartsCustomizeModelPrivate *private = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == private->stamp);
GtkTreePath *tree_path = gtk_tree_path_new();
gtk_tree_path_append_index(tree_path, GPOINTER_TO_INT(iter->user_data));
return tree_path;
}
/*! \brief Register this class's GType.
*
* \return The GType of this class.
*/
GType
gparts_customize_model_get_type( void )
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsCustomizeModelClass),
NULL,
NULL,
gparts_customize_model_class_init,
NULL,
NULL,
sizeof(GPartsCustomizeModel),
0,
gparts_customize_model_instance_init,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_customize_model_tree_model_init,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"GPartsCustomizeModel",
&tinfo,
0
);
g_type_add_interface_static(
type,
GTK_TYPE_TREE_MODEL,
&iinfo
);
}
return type;
}
/*! \brief Get a value from the tree model.
*
* This function turns invalid values into blanks. So, an invalid column or
* row will still result in a valid GValue.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [in] iter An iterator referencing the value's row.
* \param [in] column A zero based index of the value's column.
* \param [out] value The value of the cell as a GValue.
*/
static void
gparts_customize_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == privat->stamp);
if (privat->view != NULL)
{
GtkTreeViewColumn *view_column;
view_column = gtk_tree_view_get_column(privat->view, GPOINTER_TO_INT(iter->user_data));
if (view_column != NULL)
{
switch (column)
{
case 0:
g_value_init(value, G_TYPE_STRING);
g_value_set_string(value, gtk_tree_view_column_get_title(view_column));
break;
case 1:
g_value_init(value, G_TYPE_BOOLEAN);
g_value_set_boolean(value, gtk_tree_view_column_get_visible(view_column));
break;
// default:
}
}
}
/* Turn uninitialized values into blanks */
if (!G_IS_VALUE(value))
{
g_value_init(value, G_TYPE_STRING);
}
}
/*! \brief Initialize instance data.
*
* \param instance
* \param g_class
*/
static void
gparts_customize_model_instance_init(GTypeInstance* instance, gpointer g_class)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(instance);
privat->stamp = g_random_int();
}
/*! \brief Gets an iterator to a list's first child.
*
* If the parent is NULL, this function gets an iterator to the first node in
* the root list. Since this model does not implement trees, all other cases
* return FALSE.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [out] iter If successful, the first child of parent.
* \param [in] parent The parent node.
* \retval TRUE if successful and iter is valid.
* \retval FALSE if otherwise and the iter will not be valid.
*/
/*static*/ gboolean
gparts_customize_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
{
if (parent == NULL)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
iter->stamp = privat->stamp;
iter->user_data = GINT_TO_POINTER(0);
return TRUE;
}
return FALSE;
}
/*! \brief Determines if a node has children.
*
* Since this model only handles lists, this function always returns FALSE.
*
* \param [in] tree_model Unused.
* \param [out] iter Unused.
* \return FALSE, always.
*/
static gboolean
gparts_customize_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
return FALSE;
}
/*! \brief Get the next node in sequence.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [in,out] iter The node on entry. If successful, the next node.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_customize_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
gint new_position;
gint old_position;
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == privat->stamp);
old_position = GPOINTER_TO_UINT(iter->user_data);
new_position = old_position + 1;
if (new_position > old_position)
{
gint rows = gparts_customize_model_iter_n_children(tree_model, NULL);
if (new_position < rows)
{
iter->user_data = GUINT_TO_POINTER(new_position);
return TRUE;
}
}
return FALSE;
}
/*! \brief Returns the number of children a node contains.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [in] iter The given node.
* \return The number of iter's children.
*/
static gint
gparts_customize_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
gint rows = 0;
if (iter == NULL)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
if (privat->view != NULL)
{
GList *list = gtk_tree_view_get_columns(privat->view);
rows = g_list_length(list);
g_list_free(list);
}
}
return rows;
}
/*! \brief Gets an iterator to a node's nth child.
*
* If the parent is NULL, this function gets an iterator to the nth node in
* the root list. Since this model only implements lists, in all other cases,
* this function returns FALSE.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [out] iter If successful, the nth child of the parent node.
* \param [in] parent The parent node.
* \param [in] n The zero based index of the child node.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_customize_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
{
g_assert(iter != NULL);
if (parent == NULL)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(tree_model);
guint rows = gparts_customize_model_iter_n_children(tree_model, NULL);
if (n < rows)
{
iter->stamp = privat->stamp;
iter->user_data = GINT_TO_POINTER(n);
return TRUE;
}
}
return FALSE;
}
/*! \brief Obtains the parent node of a child node.
*
* Since this model only implements lists, this function always returns FALSE.
*
* \param [in] tree_model The GPartsCustomizeModel.
* \param [out] iter If successful, the parent node.
* \param [in] child The child node.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_customize_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
{
return FALSE;
}
GPartsCustomizeModel *
gparts_customize_model_new(void)
{
return g_object_new(GPARTS_TYPE_CUSTOMIZE_MODEL, NULL);
}
static void
gparts_customize_model_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch (property_id)
{
case GPARTS_CUSTOMIZE_MODEL_PROPID_VIEW:
gparts_customize_model_set_view(object, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief
*
*
*
*
*/
static void
gparts_customize_model_set_view(GObject *object, GtkTreeView *view)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(object);
if (privat->view != NULL)
{
g_object_unref(privat->view);
}
privat->view = view;
if (privat->view != NULL)
{
g_object_ref(privat->view);
}
}
void
gparts_customize_model_set_visible(GPartsCustomizeModel *model, GtkTreeIter *iter, gboolean visible)
{
GPartsCustomizeModelPrivate *privat = GPARTS_CUSTOMIZE_MODEL_GET_PRIVATE(model);
GtkTreeViewColumn *view_column;
view_column = gtk_tree_view_get_column(privat->view, GPOINTER_TO_INT(iter->user_data));
if (view_column != NULL)
{
gtk_tree_view_column_set_visible(view_column, visible);
}
}
/*! \brief Initialize the tree model interface.
*
* \param [in] iface A pointer to the tree model interface.
*/
static void
gparts_customize_model_tree_model_init(GtkTreeModelIface *iface)
{
iface->get_flags = gparts_customize_model_get_flags;
iface->get_n_columns = gparts_customize_model_get_n_columns;
iface->get_column_type = gparts_customize_model_get_column_type;
iface->get_iter = gparts_customize_model_get_iter;
iface->get_path = gparts_customize_model_get_path;
iface->get_value = gparts_customize_model_get_value;
iface->iter_next = gparts_customize_model_iter_next;
iface->iter_children = gparts_customize_model_iter_children;
iface->iter_has_child = gparts_customize_model_iter_has_child;
iface->iter_n_children = gparts_customize_model_iter_n_children;
iface->iter_nth_child = gparts_customize_model_iter_nth_child;
iface->iter_parent = gparts_customize_model_iter_parent;
}

View File

@ -0,0 +1,48 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#define GPARTS_TYPE_CUSTOMIZE_MODEL (gparts_customize_model_get_type())
#define GPARTS_CUSTOMIZE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_CUSTOMIZE_MODEL,GPartsCustomizeModel))
#define GPARTS_CUSTOMIZE_MODEL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_CUSTOMIZE_MODEL,GPartsCustomizeModelClass))
#define GPARTS_IS_CUSTOMIZE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_CUSTOMIZE_MODEL))
#define GPARTS_IS_CUSTOMIZE_MODEL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_CUSTOMIZE_MODEL))
#define GPARTS_CUSTOMIZE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_CUSTOMIZE_MODEL,GPartsCustomizeModelClass))
typedef struct _GPartsCustomizeModel GPartsCustomizeModel;
typedef struct _GPartsCustomizeModelClass GPartsCustomizeModelClass;
struct _GPartsCustomizeModel
{
GObject parent;
};
struct _GPartsCustomizeModelClass
{
GObjectClass parent;
};
GType
gparts_customize_model_get_type(void);
GPartsCustomizeModel*
gparts_customize_model_new(void);
void
gparts_customize_model_set_visible(GPartsCustomizeModel *model, GtkTreeIter *iter, gboolean visible);

View File

@ -0,0 +1,208 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include "gparts-database-result.h"
static void
gparts_database_result_base_init(gpointer g_class)
{
}
guint
gparts_database_result_get_column_count(GPartsDatabaseResult *result)
{
gint column_count = 0;
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_column_count == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_column_count() function pointer");
}
else
{
column_count = iface->get_column_count(result);
}
return column_count;
}
gboolean
gparts_database_result_get_column_index(GPartsDatabaseResult *result, const gchar *name, gint *index)
{
gboolean success = FALSE;
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_column_index == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_column_index() function pointer");
}
else
{
success = iface->get_column_index(result, name, index);
}
return success;
}
GType
gparts_database_result_get_column_type(GPartsDatabaseResult *result, gint column)
{
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
GType type = G_TYPE_INVALID;
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_column_count == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_column_type() function pointer");
}
else
{
type = iface->get_column_type(result, column);
}
return type;
}
const gchar*
gparts_database_result_get_column_units(GPartsDatabaseResult *result, gint column)
{
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
const gchar *units;
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_column_count == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_column_units() function pointer");
}
else
{
units = iface->get_column_units(result, column);
}
return units;
}
void
gparts_database_result_get_column_value(GPartsDatabaseResult *result, gint column, GValue *value)
{
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_column_value == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_column_value() function pointer");
}
else
{
iface->get_column_value(result, column, value);
}
}
void
gparts_database_result_get_field_value(GPartsDatabaseResult *result, gint row, gint column, GValue *value)
{
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_field_value == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_field_value() function pointer");
}
else
{
iface->get_field_value(result, row, column, value);
}
}
guint
gparts_database_result_get_row_count(GPartsDatabaseResult *result)
{
GPartsDatabaseResultInterface *iface = GPARTS_DATABASE_RESULT_GET_INTERFACE(result);
guint row_count = 0;
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseResultInteface from parameter");
}
else if (iface->get_row_count == NULL)
{
g_critical("GPartsDatabaseResultInterface contains NULL get_row_count() function pointer");
}
else
{
row_count = iface->get_row_count(result);
}
return row_count;
}
GType
gparts_database_result_get_type(void)
{
static GType type = 0;
if (type == 0)
{
static const GTypeInfo info = {
sizeof(GPartsDatabaseResultInterface),
gparts_database_result_base_init,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_INTERFACE,
"gparts-database-result",
&info,
0
);
}
return type;
}

View File

@ -0,0 +1,121 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-database-result.h
*
* \brief An interface for database results.
*/
#define GPARTS_TYPE_DATABASE_RESULT (gparts_database_result_get_type())
#define GPARTS_DATABASE_RESULT(object) (G_TYPE_CHECK_INSTANCE_CAST((object),GPARTS_TYPE_DATABASE_RESULT,GPartsDatabaseResult))
#define GPARTS_IS_DATABASE_RESULT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object),GPARTS_TYPE_DATABASE_RESULT))
#define GPARTS_DATABASE_RESULT_GET_INTERFACE(instance) (G_TYPE_INSTANCE_GET_INTERFACE((instance),GPARTS_TYPE_DATABASE_RESULT,GPartsDatabaseResultInterface))
typedef struct _GPartsDatabaseResult GPartsDatabaseResult;
typedef struct _GPartsDatabaseResultInterface GPartsDatabaseResultInterface;
struct _GPartsDatabaseResultInterface
{
GTypeInterface parent;
guint (*get_column_count)(GPartsDatabaseResult *result);
gboolean (*get_column_index)(GPartsDatabaseResult *result, const gchar *name, gint *index);
GType (*get_column_type)(GPartsDatabaseResult *result, gint column);
const gchar* (*get_column_units)(GPartsDatabaseResult *result, gint column);
void (*get_column_value)(GPartsDatabaseResult *result, gint column, GValue *value);
void (*get_field_value)(GPartsDatabaseResult *result, gint row, gint column, GValue *value);
guint (*get_row_count)(GPartsDatabaseResult *result);
};
/*! \brief Gets the number of columns in the database result.
*
* \param [in] result The database result.
* \return The number of columns in the database result.
*/
guint
gparts_database_result_get_column_count(GPartsDatabaseResult *result);
/*! \brief Gets the column index given the column name.
*
* \param [in] result The database result.
* \param [in] name The name of the column.
* \param [out] index The index of the column.
* \retval TRUE Success and the column index was placed in index.
* \retval FALSE The column name could not be found.
*/
gboolean
gparts_database_result_get_column_index(GPartsDatabaseResult *result, const gchar *name, gint *index);
/*! \brief Gets the type of a column.
*
* With an invalid column index, this function returns G_TYPE_INVALID.
*
* \param [in] result The database result.
* \param [in] column The zero-based index of the column.
* \return The GType of the fields in the column.
*/
GType
gparts_database_result_get_column_type(GPartsDatabaseResult *result, gint column);
/*! \brief Gets the units for a column.
*
* \param [in] result The database result.
* \param [in] column The zero-based index of the column.
*/
const gchar*
gparts_database_result_get_column_units(GPartsDatabaseResult *result, gint column);
/*! \brief Gets the name of a column.
*
* The value must be previously initialized as a G_TYPE_STRING. If an error
* occurs, the value does not get assigned.
*
* \param [in] result The database result.
* \param [in] column The zero-based index of the column.
* \param [out] value The name of the column.
*/
void
gparts_database_result_get_column_value(GPartsDatabaseResult *result, gint column, GValue *value);
/*! \brief Gets the value of a field.
*
* This function initializes and sets value to the contents of the field. The
* value parameter must not be initialized (just filled with zeros). If this
* function encounters an error, the value remains unset.
*
* \param [in] result The database result.
* \param [in] row The zero based index of the row.
* \param [in] column The zero based index of the column.
* \param [out] value The value of the field.
*/
void
gparts_database_result_get_field_value(GPartsDatabaseResult *result, gint row, gint column, GValue *value);
/*! \brief Gets the number of rows in the database result.
*
* \param [in] result The database result.
* \return The number of rows in the database result.
*/
guint
gparts_database_result_get_row_count(GPartsDatabaseResult *result);
GType
gparts_database_result_get_type(void);

201
src/gparts-database-type.c Normal file
View File

@ -0,0 +1,201 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include <gmodule.h>
#include "gparts-database-type.h"
#define GPARTS_DATABASE_TYPE_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object, GPARTS_TYPE_DATABASE_TYPE, GPartsDatabaseTypePrivate)
typedef void (*GPartsDatabaseInitFunc)(GPartsDatabaseType *database_type);
typedef struct _GPartsDatabaseTypeNode GPartsDatabaseTypeNode;
typedef struct _GPartsDatabaseTypePrivate GPartsDatabaseTypePrivate;
struct _GPartsDatabaseTypeNode
{
gchar *name;
GType type;
gint flags;
};
struct _GPartsDatabaseTypePrivate
{
GArray *modules;
};
static void
gparts_database_type_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_database_type_dispose(GObject *object);
static void
gparts_database_type_finalize(GObject *object);
static void
gparts_database_type_init(GTypeInstance *instance, gpointer g_class);
/**** ****/
void
gparts_database_type_add_type(GPartsDatabaseType *database_type, const gchar *name, GType type, gint flags)
{
GPartsDatabaseTypeNode node;
GPartsDatabaseTypePrivate *privat = GPARTS_DATABASE_TYPE_GET_PRIVATE(database_type);
node.name = g_strdup(name);
node.type = type;
node.flags = flags;
g_array_append_val(privat->modules, node);
}
static void
gparts_database_type_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass *object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsDatabaseTypePrivate));
object_class->dispose = gparts_database_type_dispose;
object_class->finalize = gparts_database_type_finalize;
((GPartsDatabaseTypeClass*)object_class)->add_type = gparts_database_type_add_type;
}
static void
gparts_database_type_dispose(GObject *object)
{
}
static void
gparts_database_type_finalize(GObject *object)
{
GPartsDatabaseTypePrivate *privat = GPARTS_DATABASE_TYPE_GET_PRIVATE(object);
g_array_free(privat->modules, TRUE);
}
gboolean
gparts_database_type_get_flags(GPartsDatabaseType *database_type, const gchar *name, gint *flags)
{
gint index;
GPartsDatabaseTypePrivate *privat = GPARTS_DATABASE_TYPE_GET_PRIVATE(database_type);
for (index=0; index<privat->modules->len; index++)
{
GPartsDatabaseTypeNode *node = &g_array_index(privat->modules, GPartsDatabaseTypeNode, index);
if (g_strcmp0(name, node->name) == 0)
{
*flags = node->flags;
return TRUE;
}
}
*flags = 0;
return FALSE;
}
GType
gparts_database_type_get_type(void)
{
static GType type = 0;
if (type == 0)
{
static const GTypeInfo tinfo = {
sizeof(GPartsDatabaseTypeClass),
NULL,
NULL,
gparts_database_type_class_init,
NULL,
NULL,
sizeof(GPartsDatabaseType),
0,
gparts_database_type_init,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"GPartsDatabaseType",
&tinfo,
0
);
}
return type;
}
static void
gparts_database_type_init(GTypeInstance* instance, gpointer g_class)
{
GPartsDatabaseTypePrivate *privat = GPARTS_DATABASE_TYPE_GET_PRIVATE(instance);
privat->modules = g_array_new(FALSE, FALSE, sizeof(GPartsDatabaseTypeNode));
}
void
gparts_database_type_load_module(GPartsDatabaseType *database_type, const gchar *name, GError **error)
{
GModule *module;
GPartsDatabaseTypePrivate *privat = GPARTS_DATABASE_TYPE_GET_PRIVATE(database_type);
module = g_module_open(name, G_MODULE_BIND_LOCAL);
if (module == NULL)
{
g_warning("%s", g_module_error());
}
else
{
GPartsDatabaseInitFunc init_func;
gboolean success;
g_array_append_val(privat->modules, module);
success = g_module_symbol(module, "gparts_database_register", (gpointer*) &init_func);
if (success == FALSE)
{
g_warning("%s", g_module_error());
}
else if (init_func == NULL)
{
g_warning("%s", g_module_error());
}
else
{
init_func(database_type);
}
}
}
GPartsDatabaseType*
gparts_database_type_new(void)
{
return g_object_new(GPARTS_TYPE_DATABASE_TYPE, NULL);
}

View File

@ -0,0 +1,79 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-database_type.h
*
* \brief A database_type for database support modules.
*/
#define GPARTS_TYPE_DATABASE_TYPE (gparts_database_type_get_type())
#define GPARTS_DATABASE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_DATABASE_TYPE,GPartsDatabaseType))
#define GPARTS_DATABASE_TYPE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_DATABASE_TYPE,GPartsDatabaseTypeClass))
#define GPARTS_IS_DATABASE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_DATABASE_TYPE))
#define GPARTS_IS_DATABASE_TYPE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_DATABASE_TYPE))
#define GPARTS_DATABASE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_DATABASE_TYPE,GPartsDatabaseTypeClass))
#define GPARTS_DATABASE_TYPE_FLAGS_USES_USERNAME (1 << 0)
#define GPARTS_DATABASE_TYPE_FLAGS_USES_PASSWORD (1 << 1)
#define GPARTS_DATABASE_TYPE_FLAGS_USES_SERVER (1 << 2)
#define GPARTS_DATABASE_TYPE_FLAGS_USES_DATABASE (1 << 3)
#define GPARTS_DATABASE_TYPE_FLAGS_USES_FILENAME (1 << 4)
typedef struct _GPartsDatabaseType GPartsDatabaseType;
typedef struct _GPartsDatabaseTypeClass GPartsDatabaseTypeClass;
struct _GPartsDatabaseType
{
GObject parent;
};
struct _GPartsDatabaseTypeClass
{
GObjectClass parent;
void (*add_type)(GPartsDatabaseType *database_type, const gchar *name, GType type, gint flags);
};
GType
gparts_database_type_get_type(void);
GPartsDatabaseType*
gparts_database_type_new();
void
gparts_database_type_load_module(GPartsDatabaseType *database_type, const gchar *name, GError **error);
/*! \brief Register a database support module
*
* \param [in] database_type The database database_type to store the information.
* \param [in] name The name of the support module.
* \param [in] type The GType to instantiate an instance of the module.
* \param [in] flags
*
* To prevent back-linking, do not call this function from the database
* module. Call this function using the function pointer in the class
* structure.
*/
void
gparts_database_type_add_type(GPartsDatabaseType *database_type, const gchar *name, GType type, gint flags);
gboolean
gparts_database_type_get_flags(GPartsDatabaseType *database_type, const gchar *name, gint *flags);

121
src/gparts-database.c Normal file
View File

@ -0,0 +1,121 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
static void
gparts_database_base_init(gpointer g_class)
{
}
void
gparts_database_connect(GPartsDatabase *database, connect_data* data, GError **error)
{
GPartsDatabaseInterface *iface = GPARTS_DATABASE_GET_INTERFACE(database);
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseInteface from parameter");
}
else if (iface->connect == NULL)
{
g_critical("GPartsDatabaseInterface contains NULL connect() function pointer");
}
else
{
iface->connect(database, data, error);
}
}
void
gparts_database_disconnect(GPartsDatabase *database, GError **error)
{
GPartsDatabaseInterface *iface = GPARTS_DATABASE_GET_INTERFACE(database);
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseInteface from parameter");
}
else if (iface->disconnect == NULL)
{
g_critical("GPartsDatabaseInterface contains NULL disconnect() function pointer");
}
else
{
iface->disconnect(database, error);
}
}
GType
gparts_database_get_type(void)
{
static GType type = 0;
if (type == 0)
{
static const GTypeInfo info = {
sizeof(GPartsDatabaseInterface),
gparts_database_base_init,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_INTERFACE,
"gparts-database",
&info,
0
);
}
return type;
}
GPartsDatabaseResult*
gparts_database_query(GPartsDatabase *database, const gchar *query, GError **error)
{
GPartsDatabaseInterface *iface = GPARTS_DATABASE_GET_INTERFACE(database);
GPartsDatabaseResult* result = NULL;
if (iface == NULL)
{
g_critical("Unable to get GPartsDatabaseInteface from parameter");
}
else if (iface->query == NULL)
{
g_critical("GPartsDatabaseInterface contains NULL query() function pointer");
}
else
{
result = iface->query(database, query, error);
}
return result;
}

90
src/gparts-database.h Normal file
View File

@ -0,0 +1,90 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \brief An interface to abstract database implementations.
*
* This interface abstracts database implementations, allowing the application
* to use different databases such as MySQL, PostreSQL, and SQLite.
*/
#define GPARTS_TYPE_DATABASE (gparts_database_get_type())
#define GPARTS_DATABASE(object) (G_TYPE_CHECK_INSTANCE_CAST((object),GPARTS_TYPE_DATABASE,GPartsDatabase))
#define GPARTS_IS_DATABASE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object),GPARTS_TYPE_DATABASE))
#define GPARTS_DATABASE_GET_INTERFACE(instance) (G_TYPE_INSTANCE_GET_INTERFACE((instance),GPARTS_TYPE_DATABASE,GPartsDatabaseInterface))
typedef struct _connect_data connect_data;
typedef struct _GPartsDatabase GPartsDatabase;
typedef struct _GPartsDatabaseInterface GPartsDatabaseInterface;
struct _GPartsDatabaseInterface
{
GTypeInterface parent;
void (*connect)(GPartsDatabase *database, connect_data* data, GError **error);
void (*disconnect)(GPartsDatabase *database, GError **error);
GPartsDatabaseResult* (*query)(GPartsDatabase *database, const gchar *query, GError **error);
const gchar* (*get_name)(GPartsDatabase *database);
};
struct _connect_data
{
gchar *host_name;
gchar *user_name;
gchar *password;
gchar *database_name;
gchar *filename;
};
/*! \brief Establishes a connection to the database.
*
* \param [in] database The database to connect to.
* \param [in] data Data needed to establish the connection.
* \param [out] error An error, if any, using the GError protocol.
*/
void
gparts_database_connect(GPartsDatabase *database, connect_data* data, GError **error);
/*! \brief Establishes a connection to the database.
*
* \param [in] database The database to disconnect from.
* \param [out] error An error, if any, using the GError protocol.
*/
void
gparts_database_disconnect(GPartsDatabase *database, GError **error);
GType
gparts_database_get_type(void);
/*! \brief Query the database
*
* \param [in] database The database to query.
* \param [in] query The SQL query to make.
* \param [out] error An error, if any, using the GError protocol.
* \return The result from the query. If unsuccessful, this function returns
* NULL.
*/
GPartsDatabaseResult*
gparts_database_query(GPartsDatabase *database, const gchar *query, GError **error);
/* TODO Move elsewhere */
void
gparts_database_register(const gchar *name, GType type);

765
src/gparts-login-ctrl.c Normal file
View File

@ -0,0 +1,765 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <string.h>
#include <gtk/gtk.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-database-type.h"
#include "gparts-login-ctrl.h"
#define GPARTS_LOGIN_CTRL_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_LOGIN_CTRL,GPartsLoginCtrlPrivate)
enum
{
GPARTS_LOGIN_CTRL_PROPID_DATABASE = 1,
GPARTS_LOGIN_CTRL_PROPID_CONNECT_ACTION,
GPARTS_LOGIN_CTRL_PROPID_DISCONNECT_ACTION,
GPARTS_LOGIN_CTRL_PROPID_REFRESH_ACTION
};
typedef struct _GPartsLoginCtrlPrivate GPartsLoginCtrlPrivate;
struct _GPartsLoginCtrlPrivate
{
GtkAction *connect_action;
GtkAction *disconnect_action;
GtkAction *refresh_action;
GPartsDatabase *database;
GPartsDatabaseType *database_type;
GtkDialog *file_dialog;
GtkDialog *login_dialog;
GtkComboBox *engine_combo;
GtkEntry *user_name_entry;
GtkEntry *password_entry;
GtkEntry *server_entry;
GtkEntry *database_entry;
GtkEntry *filename_entry;
GtkButton *button;
};
static GtkDialog*
gparts_login_ctrl_build_login_dialog(GPartsLoginCtrl *ctrl);
static void
gparts_login_ctrl_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_login_ctrl_dispose(GObject *object);
static void
gparts_login_ctrl_finalize(GObject *object);
static void
gparts_login_ctrl_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_login_ctrl_instance_init(GTypeInstance *instance, gpointer g_class);
static void
gparts_login_ctrl_set_database(GPartsLoginCtrl *ctrl, GPartsDatabase *database);
static void
gparts_login_ctrl_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
/**** Signal handlers ****/
static void
gparts_login_ctrl_changed_cb(GtkTreeSelection *selection, GPartsLoginCtrl *login_ctrl);
static void
gparts_login_ctrl_clicked_cb(GtkTreeSelection *selection, GPartsLoginCtrl *login_ctrl);
static void
gparts_login_ctrl_show_cb(GtkWidget *widget, GPartsLoginCtrl *login_ctrl);
static void
gparts_login_ctrl_connect_action_cb(GtkAction *action, GPartsLoginCtrl *login_ctrl);
static void
gparts_login_ctrl_disconnect_action_cb(GtkAction *action, GPartsLoginCtrl *login_ctrl);
static void
gparts_login_ctrl_refresh_action_cb(GtkAction *action, GPartsLoginCtrl *login_ctrl);
static GtkDialog*
gparts_login_ctrl_build_login_dialog(GPartsLoginCtrl *login_ctrl)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
GtkWidget *content, *entry, *image, *label, *button;
GtkTable *table;
privat->login_dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(
"Connect to a Database",
NULL,
GTK_DIALOG_MODAL,
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_CONNECT, GTK_RESPONSE_OK,
NULL
));
gtk_dialog_set_alternative_button_order(
privat->login_dialog,
GTK_RESPONSE_HELP,
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1
);
gtk_dialog_set_default_response(privat->login_dialog, GTK_RESPONSE_OK);
gtk_container_set_border_width(GTK_CONTAINER(privat->login_dialog), 5);
content = privat->login_dialog->vbox; //gtk_dialog_get_content_area(private->login_dialog);
gtk_box_set_spacing(GTK_BOX(content), 8);
table = GTK_TABLE(gtk_table_new(6, 4, FALSE));
gtk_table_set_row_spacings(table, 8);
gtk_table_set_col_spacings(table, 10);
GTK_WIDGET_SET_FLAGS(table, GTK_VISIBLE);
gtk_container_add(GTK_CONTAINER(content), GTK_WIDGET(table));
image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
GTK_WIDGET_SET_FLAGS(image, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
gtk_table_attach(table, GTK_WIDGET(image), 0, 1, 0, 6, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Type");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(table, GTK_WIDGET(label), 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
privat->engine_combo = GTK_COMBO_BOX(gtk_combo_box_new_text());
GTK_WIDGET_SET_FLAGS(privat->engine_combo, GTK_VISIBLE);
gtk_table_attach(table, GTK_WIDGET(privat->engine_combo), 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Username");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(table, GTK_WIDGET(label), 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
privat->user_name_entry = GTK_ENTRY(gtk_entry_new());
GTK_WIDGET_SET_FLAGS(privat->user_name_entry, GTK_VISIBLE);
gtk_table_attach(table, GTK_WIDGET(privat->user_name_entry), 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Password");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(table, label, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
privat->password_entry = GTK_ENTRY(gtk_entry_new());
g_object_set(privat->password_entry, "visibility", FALSE,NULL);
GTK_WIDGET_SET_FLAGS(privat->password_entry, GTK_VISIBLE);
gtk_table_attach(table, GTK_WIDGET(privat->password_entry), 2, 3, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Server");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(table, label, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
privat->server_entry = GTK_ENTRY(gtk_entry_new());
GTK_WIDGET_SET_FLAGS(privat->server_entry, GTK_VISIBLE);
gtk_table_attach(table, GTK_WIDGET(privat->server_entry), 2, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Database Name");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(table, label, 1, 2, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
privat->database_entry = GTK_ENTRY(gtk_entry_new());
GTK_WIDGET_SET_FLAGS(privat->database_entry, GTK_VISIBLE);
gtk_table_attach(table, GTK_WIDGET(privat->database_entry), 2, 3, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Filename");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(table, label, 1, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
privat->filename_entry = GTK_ENTRY(gtk_entry_new());
GTK_WIDGET_SET_FLAGS(privat->filename_entry, GTK_VISIBLE);
gtk_table_attach(table, GTK_WIDGET(privat->filename_entry), 2, 3, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
privat->button = gtk_button_new_with_label("...");
GTK_WIDGET_SET_FLAGS(privat->button, GTK_VISIBLE);
gtk_table_attach(table, privat->button, 3, 4, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
gtk_combo_box_append_text(privat->engine_combo, "MySQL");
gtk_combo_box_append_text(privat->engine_combo, "PostgreSQL");
gtk_combo_box_append_text(privat->engine_combo, "SQLite");
g_signal_connect(
privat->engine_combo,
"changed",
G_CALLBACK(gparts_login_ctrl_changed_cb),
login_ctrl
);
g_signal_connect(
privat->button,
"clicked",
G_CALLBACK(gparts_login_ctrl_clicked_cb),
login_ctrl
);
privat->file_dialog = gtk_file_chooser_dialog_new(
"Select File",
privat->login_dialog,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL
);
return privat->login_dialog;
}
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_login_ctrl_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsLoginCtrlPrivate));
object_class->dispose = gparts_login_ctrl_dispose;
object_class->finalize = gparts_login_ctrl_finalize;
object_class->get_property = gparts_login_ctrl_get_property;
object_class->set_property = gparts_login_ctrl_set_property;
g_object_class_install_property(
object_class,
GPARTS_LOGIN_CTRL_PROPID_CONNECT_ACTION,
g_param_spec_object(
"connect-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_LOGIN_CTRL_PROPID_DATABASE,
g_param_spec_object(
"database",
"",
"",
G_TYPE_OBJECT,
G_PARAM_READABLE
)
);
g_object_class_install_property(
object_class,
GPARTS_LOGIN_CTRL_PROPID_DISCONNECT_ACTION,
g_param_spec_object(
"disconnect-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_LOGIN_CTRL_PROPID_REFRESH_ACTION,
g_param_spec_object(
"refresh-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_signal_new(
"refresh",
G_TYPE_FROM_CLASS(g_class),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0
);
}
static void
gparts_login_ctrl_changed_cb(GtkTreeSelection *selection, GPartsLoginCtrl *login_ctrl)
{
gboolean success;
gint flags;
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
gtk_entry_set_text(privat->server_entry, "localhost");
gtk_entry_set_text(privat->database_entry, "GParts");
success = gparts_database_type_get_flags(
privat->database_type,
gtk_combo_box_get_active_text(privat->engine_combo),
&flags
);
gtk_widget_set_sensitive(
GTK_WIDGET(privat->user_name_entry),
success && (flags & GPARTS_DATABASE_TYPE_FLAGS_USES_USERNAME)
);
gtk_widget_set_sensitive(
GTK_WIDGET(privat->password_entry),
success && (flags & GPARTS_DATABASE_TYPE_FLAGS_USES_PASSWORD)
);
gtk_widget_set_sensitive(
GTK_WIDGET(privat->server_entry),
success && (flags & GPARTS_DATABASE_TYPE_FLAGS_USES_SERVER)
);
gtk_widget_set_sensitive(
GTK_WIDGET(privat->database_entry),
success && (flags & GPARTS_DATABASE_TYPE_FLAGS_USES_DATABASE)
);
gtk_widget_set_sensitive(
GTK_WIDGET(privat->filename_entry),
success && (flags & GPARTS_DATABASE_TYPE_FLAGS_USES_FILENAME)
);
gtk_widget_set_sensitive(
GTK_WIDGET(privat->button),
success && (flags & GPARTS_DATABASE_TYPE_FLAGS_USES_FILENAME)
);
}
static void
gparts_login_ctrl_clicked_cb(GtkTreeSelection *selection, GPartsLoginCtrl *login_ctrl)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
if (privat != NULL && privat->file_dialog != NULL)
{
gint result = gtk_dialog_run(privat->file_dialog);
if (result == GTK_RESPONSE_OK)
{
gchar *filename = gtk_file_chooser_get_filename(privat->file_dialog);
gtk_entry_set_text(privat->filename_entry, filename);
g_free(filename);
}
gtk_widget_hide(privat->file_dialog);
}
}
static void
gparts_login_ctrl_connect_action_cb(GtkAction *action, GPartsLoginCtrl *login_ctrl)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
gint result;
gtk_entry_set_text(privat->user_name_entry, g_get_user_name());
gtk_entry_set_text(privat->password_entry, "");
gtk_combo_box_set_active(privat->engine_combo, 0);
result = gtk_dialog_run(privat->login_dialog);
#if 1
if (result == GTK_RESPONSE_OK)
{
GPartsDatabase *database;
connect_data data;
GError *error = NULL;
data.user_name = gtk_entry_get_text(privat->user_name_entry);
data.password = gtk_entry_get_text(privat->password_entry);
data.host_name = gtk_entry_get_text(privat->server_entry);
data.database_name = gtk_entry_get_text(privat->database_entry);
database = g_object_new(g_type_from_name("gparts-mysql-database"), NULL);
gparts_database_connect(database, &data, &error);
if (error != NULL)
{
GtkWidget *error_dialog = gtk_message_dialog_new(
GTK_WINDOW(privat->login_dialog),
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s",
error->message
);
gtk_dialog_run(GTK_DIALOG(error_dialog));
gtk_widget_destroy(error_dialog);
g_critical("%s", error->message);
g_clear_error(&error);
}
else
{
gparts_login_ctrl_set_database(login_ctrl, database);
}
g_object_unref(database);
}
#endif
gtk_widget_hide(GTK_WIDGET(privat->login_dialog));
}
static void
gparts_login_ctrl_disconnect_action_cb(GtkAction *action, GPartsLoginCtrl *login_ctrl)
{
gparts_login_ctrl_set_database(login_ctrl, NULL);
}
static void
gparts_login_ctrl_dispose(GObject *object)
{
gparts_login_ctrl_set_database(GPARTS_LOGIN_CTRL(object), NULL);
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_login_ctrl_finalize(GObject *object)
{
GPartsLoginCtrlPrivate *private = GPARTS_LOGIN_CTRL_GET_PRIVATE(object);
}
/*! \brief Gets the GType of the GPartsLoginCtrl class.
*
* \return The GType of the GPartsLoginCtrl class.
*/
GType
gparts_login_ctrl_get_type(void)
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsLoginCtrlClass),
NULL,
NULL,
gparts_login_ctrl_class_init,
NULL,
NULL,
sizeof(GPartsLoginCtrl),
0,
gparts_login_ctrl_instance_init,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-database-ctrl",
&tinfo,
0
);
}
return type;
}
GPartsDatabase*
gparts_login_ctrl_get_database(GPartsLoginCtrl *login_ctrl)
{
GPartsDatabase *database = NULL;
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
if (privat != NULL)
{
database = privat->database;
}
return database;
}
static void
gparts_login_ctrl_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(object);
switch (property_id)
{
case GPARTS_LOGIN_CTRL_PROPID_CONNECT_ACTION:
g_value_set_object(value, privat->connect_action);
break;
case GPARTS_LOGIN_CTRL_PROPID_DATABASE:
g_value_set_object(value, gparts_login_ctrl_get_database(GPARTS_LOGIN_CTRL(object)));
break;
case GPARTS_LOGIN_CTRL_PROPID_DISCONNECT_ACTION:
g_value_set_object(value, privat->disconnect_action);
break;
case GPARTS_LOGIN_CTRL_PROPID_REFRESH_ACTION:
g_value_set_object(value, privat->refresh_action);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
static void
gparts_login_ctrl_instance_init(GTypeInstance *instance, gpointer g_class)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(instance);
privat->login_dialog = gparts_login_ctrl_build_login_dialog(GPARTS_LOGIN_CTRL(instance));
privat->database_type = gparts_database_type_new();
/** TODO Move elsewhere */
gparts_database_type_load_module(privat->database_type, "libgparts-mysql.la", NULL);
/* TODO Test code / Remove before flight */
gparts_database_type_add_type(
privat->database_type,
"PostgreSQL",
G_TYPE_INVALID,
GPARTS_DATABASE_TYPE_FLAGS_USES_USERNAME
);
gparts_database_type_add_type(
privat->database_type,
"SQLite",
G_TYPE_INVALID,
GPARTS_DATABASE_TYPE_FLAGS_USES_FILENAME
);
}
static void
gparts_login_ctrl_refresh_action_cb(GtkAction *action, GPartsLoginCtrl *login_ctrl)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
if (privat != NULL && privat->database != NULL)
{
g_signal_emit_by_name(login_ctrl, "refresh");
}
}
void
gparts_login_ctrl_set_connect_action(GPartsLoginCtrl *login_ctrl, GtkAction *action)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
if (privat->connect_action != action)
{
if (privat->connect_action != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->connect_action,
G_CALLBACK(gparts_login_ctrl_connect_action_cb),
login_ctrl
);
g_object_unref(privat->connect_action);
}
privat->connect_action = action;
if (privat->connect_action != NULL)
{
g_object_ref(privat->connect_action);
g_signal_connect(
privat->connect_action,
"activate",
G_CALLBACK(gparts_login_ctrl_connect_action_cb),
login_ctrl
);
}
g_object_notify(G_OBJECT(login_ctrl), "connect-action");
}
}
void
gparts_login_ctrl_set_disconnect_action(GPartsLoginCtrl *login_ctrl, GtkAction *action)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(login_ctrl);
if (privat->disconnect_action != action)
{
if (privat->disconnect_action != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->disconnect_action,
G_CALLBACK(gparts_login_ctrl_disconnect_action_cb),
login_ctrl
);
g_object_unref(privat->disconnect_action);
}
privat->disconnect_action = action;
if (privat->disconnect_action != NULL)
{
g_object_ref(privat->disconnect_action);
g_signal_connect(
privat->disconnect_action,
"activate",
G_CALLBACK(gparts_login_ctrl_disconnect_action_cb),
login_ctrl
);
gtk_action_set_sensitive(privat->disconnect_action, (privat->database != NULL));
}
g_object_notify(G_OBJECT(login_ctrl), "disconnect-action");
}
}
static void
gparts_login_ctrl_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
GPartsLoginCtrl *login_ctrl = GPARTS_LOGIN_CTRL(object);
switch (property_id)
{
case GPARTS_LOGIN_CTRL_PROPID_CONNECT_ACTION:
gparts_login_ctrl_set_connect_action(login_ctrl, g_value_get_object(value));
break;
case GPARTS_LOGIN_CTRL_PROPID_DISCONNECT_ACTION:
gparts_login_ctrl_set_disconnect_action(login_ctrl, g_value_get_object(value));
break;
case GPARTS_LOGIN_CTRL_PROPID_REFRESH_ACTION:
gparts_login_ctrl_set_refresh_action(login_ctrl, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
static void
gparts_login_ctrl_set_database(GPartsLoginCtrl *ctrl, GPartsDatabase *database)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(ctrl);
if (privat->database != database)
{
if (privat->database != NULL)
{
g_object_unref(privat->database);
}
privat->database = database;
if (privat->database != NULL)
{
g_object_ref(privat->database);
}
if (privat->disconnect_action != NULL)
{
gtk_action_set_sensitive(privat->disconnect_action, (privat->database != NULL));
}
if (privat->refresh_action != NULL)
{
gtk_action_set_sensitive(privat->refresh_action, (privat->database != NULL));
}
g_object_notify(G_OBJECT(ctrl), "database");
}
}
void
gparts_login_ctrl_set_refresh_action(GPartsLoginCtrl *ctrl, GtkAction *action)
{
GPartsLoginCtrlPrivate *privat = GPARTS_LOGIN_CTRL_GET_PRIVATE(ctrl);
if (privat->refresh_action != action)
{
if (privat->refresh_action != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->refresh_action,
G_CALLBACK(gparts_login_ctrl_refresh_action_cb),
ctrl
);
g_object_unref(privat->refresh_action);
}
privat->refresh_action = action;
if (privat->refresh_action != NULL)
{
g_object_ref(privat->refresh_action);
g_signal_connect(
privat->refresh_action,
"activate",
G_CALLBACK(gparts_login_ctrl_refresh_action_cb),
ctrl
);
gtk_action_set_sensitive(privat->refresh_action, (privat->database != NULL));
}
g_object_notify(G_OBJECT(ctrl), "refresh-action");
}
}

78
src/gparts-login-ctrl.h Normal file
View File

@ -0,0 +1,78 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-login-ctrl.h
*/
#define GPARTS_TYPE_LOGIN_CTRL (gparts_login_ctrl_get_type())
#define GPARTS_LOGIN_CTRL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_LOGIN_CTRL,GPartsLoginCtrl))
#define GPARTS_LOGIN_CTRL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_LOGIN_CTRL,GPartsLoginCtrlClass))
#define GPARTS_IS_LOGIN_CTRL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_LOGIN_CTRL))
#define GPARTS_IS_LOGIN_CTRL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_LOGIN_CTRL))
#define GPARTS_LOGIN_CTRL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_LOGIN_CTRL,GPartsLoginCtrlClass))
typedef struct _GPartsLoginCtrl GPartsLoginCtrl;
typedef struct _GPartsLoginCtrlClass GPartsLoginCtrlClass;
struct _GPartsLoginCtrl
{
GObject parent;
};
struct _GPartsLoginCtrlClass
{
GObjectClass parent;
};
GType
gparts_login_ctrl_get_type(void);
/*! \brief Gets the database currently associated with this controller.
*
* \param [in] login_ctrl The login controller.
* \return The database associated with this ctrl. If no database, then NULL.
*/
GPartsDatabase*
gparts_login_ctrl_get_database(GPartsLoginCtrl *login_ctrl);
/*! \brief Sets the action to connect to a database.
*
* \param [in] login_ctrl The login controller.
* \param [in] action The action that triggers the connect.
*/
void
gparts_login_ctrl_set_connect_action(GPartsLoginCtrl *login_ctrl, GtkAction *action);
/*! \brief Sets the action to disconnect from the database.
*
* \param [in] login_ctrl The login controller.
* \param [in] action The action that triggers the disconnect.
*/
void
gparts_login_ctrl_set_disconnect_action(GPartsLoginCtrl *login_ctrl, GtkAction *action);
/*! \brief Sets the action to refresh all database views.
*
* \param [in] login_ctrl The login controller.
* \param [in] action The action that triggers the refresh.
*/
void
gparts_login_ctrl_set_refresh_action(GPartsLoginCtrl *login_ctrl, GtkAction *action);

464
src/gparts-login-dialog.c Normal file
View File

@ -0,0 +1,464 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-login-dialog.h"
enum
{
GPARTS_LOGIN_DIALOG_PROPID_DATABASE = 1,
};
typedef struct _GPartsLoginDialogPrivate GPartsLoginDialogPrivate;
struct _GPartsLoginDialogPrivate
{
GtkDialog *dialog;
};
#define GPARTS_LOGIN_DIALOG_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_LOGIN_DIALOG,GPartsLoginDialogPrivate)
static void
gparts_login_dialog_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_login_dialog_dispose(GObject *object);
static void
gparts_login_dialog_finalize(GObject *object);
static void
gparts_login_dialog_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_login_dialog_instance_init(GTypeInstance *instance, gpointer g_class);
static void
gparts_login_dialog_set_database(GPartsLoginDialog *controller, GPartsDatabase *database);
static void
gparts_login_dialog_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
/**** Signal handlers ****/
static void
gparts_login_dialog_changed_cb(GtkTreeSelection *selection, GPartsLoginDialog *controller);
static void
gparts_login_dialog_show_cb(GtkWidget *widget, GPartsLoginDialog *controller);
static void
gparts_login_dialog_connect_action_cb(GtkAction *action, GPartsLoginDialog *controller);
static void
gparts_login_dialog_disconnect_action_cb(GtkAction *action, GPartsLoginDialog *controller);
static void
gparts_login_dialog_refresh_action_cb(GtkAction *action, GPartsLoginDialog *controller);
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_login_dialog_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsLoginDialogPrivate));
object_class->dispose = gparts_login_dialog_dispose;
object_class->finalize = gparts_login_dialog_finalize;
object_class->get_property = gparts_login_dialog_get_property;
object_class->set_property = gparts_login_dialog_set_property;
g_object_class_install_property(
object_class,
GPARTS_LOGIN_DIALOG_PROPID_CONNECT_ACTION,
g_param_spec_object(
"connect-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_LOGIN_DIALOG_PROPID_DATABASE,
g_param_spec_object(
"database",
"",
"",
G_TYPE_OBJECT,
G_PARAM_READABLE
)
);
g_object_class_install_property(
object_class,
GPARTS_LOGIN_DIALOG_PROPID_DISCONNECT_ACTION,
g_param_spec_object(
"disconnect-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_LOGIN_DIALOG_PROPID_REFRESH_ACTION,
g_param_spec_object(
"refresh-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_signal_new(
"refresh",
G_TYPE_FROM_CLASS(g_class),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0
);
}
static void
gparts_login_dialog_changed_cb(GtkTreeSelection *selection, GPartsLoginDialog *controller)
{
GPartsLoginDialogPrivate *privat = GPARTS_LOGIN_DIALOG_GET_PRIVATE(controller);
gtk_entry_set_text(privat->server_entry, "localhost");
gtk_entry_set_text(privat->database_entry, "GParts");
}
static void
gparts_login_dialog_connect_action_cb(GtkAction *action, GPartsLoginDialog *controller)
{
GPartsLoginDialogPrivate *private = GPARTS_LOGIN_DIALOG_GET_PRIVATE(controller);
gint result;
gtk_entry_set_text(private->user_name_entry, g_get_user_name());
gtk_entry_set_text(private->password_entry, "");
gtk_combo_box_set_active(private->engine_combo, 0);
result = gtk_dialog_run(private->login_dialog);
#if 1
if (result == GTK_RESPONSE_ACCEPT)
{
GPartsDatabase *database;
connect_data data;
GError *error = NULL;
data.user_name = gtk_entry_get_text(private->user_name_entry);
data.password = gtk_entry_get_text(private->password_entry);
data.host_name = gtk_entry_get_text(private->server_entry);
data.database_name = gtk_entry_get_text(private->database_entry);
database = g_object_new(g_type_from_name("gparts-mysql-database"), NULL);
gparts_database_connect(database, &data, &error);
if (error != NULL)
{
GtkWidget *error_dialog = gtk_message_dialog_new(
private->login_dialog,
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s",
error->message
);
gtk_dialog_run(GTK_DIALOG(error_dialog));
gtk_widget_destroy(error_dialog);
g_critical("%s", error->message);
g_clear_error(&error);
}
else
{
gparts_login_dialog_set_database(controller, database);
}
g_object_unref(database);
}
#endif
gtk_widget_hide(GTK_WIDGET(private->login_dialog));
}
static void
gparts_login_dialog_disconnect_action_cb(GtkAction *action, GPartsLoginDialog *controller)
{
gparts_login_dialog_set_database(controller, NULL);
}
static void
gparts_login_dialog_dispose(GObject *object)
{
gparts_login_dialog_set_database(object, NULL);
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_login_dialog_finalize(GObject *object)
{
GPartsLoginDialogPrivate *private = GPARTS_LOGIN_DIALOG_GET_PRIVATE(object);
g_array_free(private->view_controllers, TRUE);
}
/*! \brief Gets the GType of the GPartsLoginDialog class.
*
* \return The GType of the GPartsLoginDialog class.
*/
GType
gparts_login_dialog_get_type(void)
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsLoginDialogClass),
NULL,
NULL,
gparts_login_dialog_class_init,
NULL,
NULL,
sizeof(GPartsLoginDialog),
0,
gparts_login_dialog_instance_init,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-database-controller",
&tinfo,
0
);
}
return type;
}
GPartsDatabase*
gparts_login_dialog_get_database(GPartsLoginDialog *controller)
{
GPartsDatabase *database = NULL;
GPartsLoginDialogPrivate *privat = GPARTS_LOGIN_DIALOG_GET_PRIVATE(controller);
if (privat != NULL)
{
database = privat->database;
}
return database;
}
static void
gparts_login_dialog_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsLoginDialogPrivate *privat = GPARTS_LOGIN_DIALOG_GET_PRIVATE(object);
switch (property_id)
{
case GPARTS_LOGIN_DIALOG_PROPID_CONNECT_ACTION:
g_value_set_object(value, privat->connect_action);
break;
case GPARTS_LOGIN_DIALOG_PROPID_DATABASE:
g_value_set_object(value, gparts_login_dialog_get_database(object));
break;
case GPARTS_LOGIN_DIALOG_PROPID_DISCONNECT_ACTION:
g_value_set_object(value, privat->disconnect_action);
break;
case GPARTS_LOGIN_DIALOG_PROPID_REFRESH_ACTION:
g_value_set_object(value, privat->refresh_action);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
static void
gparts_login_dialog_instance_init(GTypeInstance *instance, gpointer g_class)
{
GPartsLoginDialogPrivate *privat = GPARTS_LOGIN_DIALOG_GET_PRIVATE(instance);
privat->dialog = gtk_dialog_new_with_buttons(
"Connect to a Database",
NULL,
GTK_DIALOG_MODAL,
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT,
NULL
);
gtk_dialog_set_default_response(private->login_dialog, GTK_RESPONSE_OK);
content = private->login_dialog->vbox; //gtk_dialog_get_content_area(private->login_dialog);
table = gtk_table_new(6, 3, FALSE);
GTK_WIDGET_SET_FLAGS(table, GTK_VISIBLE);
gtk_container_add(GTK_CONTAINER(content), table);
image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
GTK_WIDGET_SET_FLAGS(image, GTK_VISIBLE);
gtk_table_attach(table, image, 0, 1, 0, 6, GTK_FILL, GTK_SHRINK, 0, 0);
label = gtk_label_new("Engine");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_table_attach(table, label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
private->engine_combo = gtk_combo_box_new_text();
GTK_WIDGET_SET_FLAGS(private->engine_combo, GTK_VISIBLE);
gtk_table_attach(table, private->engine_combo, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Username");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_table_attach(table, label, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
private->user_name_entry = gtk_entry_new();
GTK_WIDGET_SET_FLAGS(private->user_name_entry, GTK_VISIBLE);
gtk_table_attach(table, private->user_name_entry, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Password");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_table_attach(table, label, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
private->password_entry = gtk_entry_new();
g_object_set(private->password_entry, "visibility", FALSE,NULL);
GTK_WIDGET_SET_FLAGS(private->password_entry, GTK_VISIBLE);
gtk_table_attach(table, private->password_entry, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Server");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_table_attach(table, label, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
private->server_entry = gtk_entry_new();
GTK_WIDGET_SET_FLAGS(private->server_entry, GTK_VISIBLE);
gtk_table_attach(table, private->server_entry, 2, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Database");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_table_attach(table, label, 1, 2, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
private->database_entry = gtk_entry_new();
GTK_WIDGET_SET_FLAGS(private->database_entry, GTK_VISIBLE);
gtk_table_attach(table, private->database_entry, 2, 3, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Filename");
GTK_WIDGET_SET_FLAGS(label, GTK_VISIBLE);
gtk_table_attach(table, label, 1, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
private->filename_entry = gtk_entry_new();
GTK_WIDGET_SET_FLAGS(private->filename_entry, GTK_VISIBLE);
gtk_table_attach(table, private->filename_entry, 2, 3, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
gtk_combo_box_append_text(private->engine_combo, "MySQL");
gtk_combo_box_append_text(private->engine_combo, "PostgreSQL");
gtk_combo_box_append_text(private->engine_combo, "SQLite");
g_signal_connect(
private->engine_combo,
"changed",
G_CALLBACK(gparts_login_dialog_changed_cb),
instance
);
}
static void
gparts_login_dialog_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch (property_id)
{
case GPARTS_LOGIN_DIALOG_PROPID_REFRESH_ACTION:
gparts_login_dialog_set_refresh_action(object, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
static void
gparts_login_dialog_set_database(GPartsLoginDialog *controller, GPartsDatabase *database)
{
GPartsLoginDialogPrivate *privat = GPARTS_LOGIN_DIALOG_GET_PRIVATE(controller);
if (privat->database != database)
{
if (privat->database != NULL)
{
g_object_unref(privat->database);
}
privat->database = database;
if (privat->database != NULL)
{
g_object_ref(privat->database);
}
if (privat->disconnect_action != NULL)
{
gtk_action_set_sensitive(privat->disconnect_action, (privat->database != NULL));
}
if (privat->refresh_action != NULL)
{
gtk_action_set_sensitive(privat->refresh_action, (privat->database != NULL));
}
g_object_notify(G_OBJECT(controller), "database");
}
}

46
src/gparts-login-dialog.h Normal file
View File

@ -0,0 +1,46 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-database-controller.h
*/
#define GPARTS_TYPE_LOGIN_DIALOG (gparts_login_dialog_get_type())
#define GPARTS_LOGIN_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_LOGIN_DIALOG,GPARTSLoginDialog))
#define GPARTS_LOGIN_DIALOG_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_LOGIN_DIALOG,GPARTSLoginDialogClass))
#define GPARTS_IS_LOGIN_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_LOGIN_DIALOG))
#define GPARTS_IS_LOGIN_DIALOG_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_LOGIN_DIALOG))
#define GPARTS_LOGIN_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_LOGIN_DIALOG,GPARTSLoginDialogClass))
typedef struct _GPartsLoginDialog GPartsLoginDialog;
typedef struct _GPartsLoginDialogClass GPartsLoginDialogClass;
struct _GPartsLoginDialog
{
GObject parent;
};
struct _GPartsLoginDialogClass
{
GObjectClass parent;
};
GType
gparts_login_dialog_get_type(void);

316
src/gparts-main.c Normal file
View File

@ -0,0 +1,316 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-main.h"
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-result-model.h"
#include "gparts-category-model.h"
#include "gparts-preview.h"
#include "gparts-mysql-database.h"
#include "gparts-customize-ctrl.h"
#include "gparts-login-ctrl.h"
#include "gparts-result-controller.h"
#include "gparts-category-controller.h"
#include "gparts-object-list.h"
#include "gparts-result-view.h"
#define GPARTS_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object, GPARTS_TYPE, GPartsPrivate)
typedef struct _GPartsPrivate GPartsPrivate;
struct _GPartsPrivate
{
GtkBuilder *builder;
GPartsObjectList *controllers;
};
/**** Static methods ****/
static void
gparts_instance_init(GTypeInstance *instance, gpointer g_class);
static void
gparts_dispose(GObject *object);
static void
gparts_finalize(GObject *object);
static void
gparts_set_database(GParts *gparts, GPartsDatabase *database);
/**** Signal handlers ****/
static void
gparts_action_edit_preferences_cb(GtkWidget* widget, gpointer data);
static void
gparts_destroy_cb(GtkWidget* widget, gpointer data);
static void
gparts_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsPrivate));
object_class->dispose = gparts_dispose;
object_class->finalize = gparts_finalize;
}
static void
gparts_destroy_cb(GtkWidget* widget, gpointer data)
{
g_object_unref(G_OBJECT(data));
gtk_main_quit();
}
static void
gparts_dispose(GObject *object)
{
GPartsPrivate *privat = GPARTS_GET_PRIVATE(object);
g_object_unref(privat->builder);
g_object_unref(privat->controllers);
}
static void
gparts_finalize(GObject *object)
{
}
GType
gparts_get_type( void )
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo info = {
sizeof(GPartsClass),
NULL,
NULL,
gparts_class_init,
NULL,
NULL,
sizeof(GParts),
0,
gparts_instance_init,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts",
&info,
0
);
}
return type;
}
GParts *gparts_new(void)
{
return g_object_new(GPARTS_TYPE, NULL);
}
static void
gparts_instance_init(GTypeInstance* instance, gpointer g_class)
{
GtkAction *action;
GError* error = NULL;
guint status;
GPartsPrivate *private = GPARTS_GET_PRIVATE(instance);
GPARTS_TYPE_PREVIEW;
//GPARTS_TYPE_RESULT_TREE;
GPARTS_TYPE_OBJECT_LIST;
GPARTS_TYPE_RESULT_VIEW;
private->builder = gtk_builder_new();
status = gtk_builder_add_from_file(
private->builder,
"gparts.xml",
&error
);
if ( status == 0 )
{
g_error( error->message ) ;
}
gtk_builder_connect_signals(private->builder, NULL);
GtkWidget *widget = GTK_WIDGET(gtk_builder_get_object(private->builder, "main"));
g_signal_connect(
G_OBJECT(widget),
"destroy",
G_CALLBACK(gparts_destroy_cb),
instance
);
private->controllers = GPARTS_OBJECT_LIST(gtk_builder_get_object(private->builder, "controllers"));
/**** Controllers ****/
GObject *customize_ctrl = g_object_new(
GPARTS_TYPE_CUSTOMIZE_CTRL,
"customize-action", GTK_ACTION(gtk_builder_get_object(private->builder, "view-customize")),
NULL
);
GObject *login_ctrl = g_object_new(
GPARTS_TYPE_LOGIN_CTRL,
"connect-action", GTK_ACTION(gtk_builder_get_object(private->builder, "database-connect")),
"disconnect-action", GTK_ACTION(gtk_builder_get_object(private->builder, "database-disconnect")),
"refresh-action", GTK_ACTION(gtk_builder_get_object(private->builder, "view-refresh")),
NULL
);
/**** "High" level controllers ****/
GObject *category_controller = g_object_new(
GPARTS_TYPE_CATEGORY_CONTROLLER,
"database-controller", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "category-view")),
NULL
);
GObject *part_controller = g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"edit-action", GTK_ACTION(gtk_builder_get_object(private->builder, "view-edit")),
"source", category_controller,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "parts-tree-view")),
"template", "SELECT * FROM %s",
"view-name", "$(ViewName)",
NULL
);
GObject *symbol_controller = g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"source", part_controller,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "symbols-tree-view")),
"template", "SELECT * FROM %s WHERE DeviceID = $(DeviceID)",
"view-name", "SymbolV",
NULL
);
g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "companies-view")),
"template", "SELECT * FROM %s",
"view-name", "CompanyV",
NULL
);
g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "devices-view")),
"template", "SELECT * FROM %s",
"view-name", "DeviceV",
NULL
);
g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "documentation-view")),
"template", "SELECT * FROM %s",
"view-name", "DocumentV",
NULL
);
g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "footprints-view")),
"template", "SELECT * FROM %s",
"view-name", "FootprintV",
NULL
);
g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "packages-view")),
"template", "SELECT * FROM %s",
"view-name", "PackageV",
NULL
);
GObject *symbol_controller2 = g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "symbols-view")),
"template", "SELECT * FROM %s",
"view-name", "SymbolV",
NULL
);
g_object_new(
GPARTS_TYPE_RESULT_CONTROLLER,
"customize-ctrl", customize_ctrl,
"database-ctrl", login_ctrl,
"source", symbol_controller2,
"target", GTK_TREE_VIEW(gtk_builder_get_object(private->builder, "symbol-details-view")),
"template", "SELECT * FROM %s WHERE SymbolID = $(SymbolID)",
"view-name", "SymbolDetail",
NULL
);
//"customize-dialog", NULL,
gtk_widget_show(widget);
}
int main(int argc, char* argv[])
{
GParts *gparts;
g_type_init();
gtk_init(&argc, &argv);
gparts = gparts_new();
gtk_main();
return 0;
}

20
src/gparts-main.h Normal file
View File

@ -0,0 +1,20 @@
#define GPARTS_TYPE (gparts_get_type())
#define GPARTS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), GPARTS_TYPE, GParts))
typedef struct _GParts GParts;
typedef struct _GPartsClass GPartsClass;
struct _GParts
{
GObject parent;
};
struct _GPartsClass
{
GObjectClass parent;
};
GType gparts_get_type(void);
GParts *gparts_new(void);

372
src/gparts-mysql-database.c Normal file
View File

@ -0,0 +1,372 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include <gmodule.h>
#include <mysql.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-mysql-result.h"
#include "gparts-mysql-database.h"
typedef struct _GPartsMySQLDatabasePrivate GPartsMySQLDatabasePrivate;
struct _GPartsMySQLDatabasePrivate
{
MYSQL* mysql;
};
#define GPARTS_MYSQL_DATABASE_ERROR (gparts_mysql_database_error_quark())
#define GPARTS_MYSQL_DATABASE_GET_PRIVATE(database) G_TYPE_INSTANCE_GET_PRIVATE(database,GPARTS_TYPE_MYSQL_DATABASE,GPartsMySQLDatabasePrivate);
static void
gparts_mysql_database_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_mysql_database_connect(GPartsDatabase *database, connect_data *data, GError **error);
static void
gparts_mysql_database_database_init(GPartsDatabaseInterface *iface);
static void
gparts_mysql_database_disconnect(GPartsDatabase *database, GError **error);
static void
gparts_mysql_database_dispose(GObject *object);
static GQuark
gparts_mysql_database_error_quark(void);
static void
gparts_mysql_database_finalize(GObject *object);
static void
gparts_mysql_database_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_mysql_database_instance_init(GTypeInstance *instance, gpointer g_class);
GPartsMySQLResult*
gparts_mysql_database_query(GPartsDatabase *database, const gchar *query, GError **error);
static void
gparts_mysql_database_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_mysql_database_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass *object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(
g_class,
sizeof(GPartsMySQLDatabasePrivate)
);
object_class->finalize = gparts_mysql_database_finalize;
object_class->get_property = gparts_mysql_database_get_property;
object_class->set_property = gparts_mysql_database_set_property;
g_signal_new(
"database-connected",
G_TYPE_FROM_CLASS( g_class ),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0
);
g_signal_new(
"database-disconnected",
G_TYPE_FROM_CLASS( g_class ),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0
);
}
/** \brief Connects to the MySQL database.
*
* Connects to an existing MySQL database.
*
* \param [in] database
* \param [in] data
* \param [in] error
*/
static void
gparts_mysql_database_connect(GPartsDatabase *database, connect_data *data, GError **error)
{
GError *local_error = NULL;
GPartsMySQLDatabasePrivate* private;
g_assert( database != NULL );
private = GPARTS_MYSQL_DATABASE_GET_PRIVATE( database );
g_assert( private != NULL );
gparts_mysql_database_disconnect(database, &local_error);
if ( local_error == NULL )
{
MYSQL* result;
private->mysql = mysql_init( NULL );
result = mysql_real_connect(
private->mysql,
data->host_name,
data->user_name,
data->password,
data->database_name,
0,
NULL,
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS
);
if ( private->mysql != result )
{
g_set_error(
&local_error,
GPARTS_MYSQL_DATABASE_ERROR,
mysql_errno( private->mysql ),
"%s",
mysql_error( private->mysql )
);
}
}
if ( local_error == NULL )
{
g_signal_emit_by_name( database, "database-connected" );
}
else
{
g_propagate_error( error, local_error );
}
}
/*! \brief
*
* \param [in] iface
*/
static void
gparts_mysql_database_database_init(GPartsDatabaseInterface *iface)
{
iface->connect = gparts_mysql_database_connect;
iface->disconnect = gparts_mysql_database_disconnect;
iface->query = gparts_mysql_database_query;
}
/*! \brief Disconnects from the MySQL database.
*
* \param [in] database The database to disconnect from.
* \param [out] error An error, if any, using the GError protocol.
*/
static void
gparts_mysql_database_disconnect(GPartsDatabase *database, GError **error)
{
GPartsMySQLDatabasePrivate* private;
g_assert(database != NULL);
private = GPARTS_MYSQL_DATABASE_GET_PRIVATE(database);
g_assert(private != NULL);
if (private->mysql != NULL)
{
mysql_close(private->mysql);
private->mysql = NULL;
g_signal_emit_by_name(database, "database-disconnected");
}
}
/*!
*
*
*
*/
static GQuark
gparts_mysql_database_error_quark(void)
{
return g_quark_from_static_string( "gparts-database-mysql-error" );
}
/*! \brief Free all resources
*
* \param [in] object
*/
static void
gparts_mysql_database_finalize(GObject *object)
{
g_debug("gparts_mysql_database_finalize()");
}
static void
gparts_mysql_database_get_property( GObject* object, guint property_id, GValue* value, GParamSpec* param_spec )
{
}
GType
gparts_mysql_database_get_type( void )
{
static GType type = 0;
if (type == 0)
{
static const GTypeInfo tinfo = {
sizeof(GPartsMySQLDatabaseClass),
NULL,
NULL,
gparts_mysql_database_class_init,
NULL,
NULL,
sizeof(GPartsMySQLDatabase),
0,
NULL,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_mysql_database_database_init,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-mysql-database",
&tinfo,
0
);
if (type != G_TYPE_INVALID)
{
g_type_add_interface_static(
type,
GPARTS_TYPE_DATABASE,
&iinfo
);
}
}
return type;
}
/**
* \brief Creates a new IBIS model.
*/
GPartsMySQLDatabase* gparts_mysql_database_new()
{
return GPARTS_MYSQL_DATABASE(g_object_new(GPARTS_TYPE_MYSQL_DATABASE, NULL));
}
/*! \brief Execute an SQL query to the database.
*
* \param [in] database The database to query.
* \param [in] query The SQL query as a string.
* \param [out] error An error, if any, using the GError protocol.
*/
GPartsMySQLResult*
gparts_mysql_database_query(GPartsDatabase *database, const gchar *query, GError **error)
{
MYSQL_RES *result;
GPartsMySQLDatabasePrivate* private;
int status;
g_assert(database != NULL);
g_assert(query != NULL);
private = GPARTS_MYSQL_DATABASE_GET_PRIVATE( database );
g_assert( private != NULL );
if (private->mysql == NULL)
{
return NULL;
}
status = mysql_query(private->mysql, query);
if ( status != 0 )
{
g_debug("Database error: %s", mysql_error(private->mysql));
g_set_error(
error,
GPARTS_MYSQL_DATABASE_ERROR,
mysql_errno(private->mysql),
"%s",
mysql_error(private->mysql)
);
return NULL;
}
result = mysql_store_result(private->mysql);
if ( result == NULL )
{
g_debug("Database error: %s", mysql_error(private->mysql));
g_set_error(
error,
GPARTS_MYSQL_DATABASE_ERROR,
mysql_errno(private->mysql),
"%s",
mysql_error(private->mysql)
);
return NULL;
}
return gparts_mysql_result_new(result);
}
/**
* \brief Loads an IBIS model from a file.
*
* After loading, the model object emits a "model-changed" signal.
*
* @param model
* @param filename
* @param error The error, if any, using standard GLib conventions.
*/
static void
gparts_mysql_database_set_property( GObject* object, guint property_id, const GValue* value, GParamSpec* param_spec )
{
g_print( "Set property: %d\n", property_id );
}

View File

@ -0,0 +1,46 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#define GPARTS_TYPE_MYSQL_DATABASE (gparts_mysql_database_get_type())
#define GPARTS_MYSQL_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_MYSQL_DATABASE,GPartsMySQLDatabase))
#define GPARTS_MYSQL_DATABASE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_MYSQL_DATABASE,GPartsMySQLDatabaseClass))
#define GPARTS_IS_MYSQL_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_MYSQL_DATABASE))
#define GPARTS_IS_MYSQL_DATABASE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_MYSQL_DATABASE))
#define GPARTS_MYSQL_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_MYSQL_DATABASE,GPartsMySQLDatabaseClass))
typedef struct _GPartsMySQLDatabase GPartsMySQLDatabase;
typedef struct _GPartsMySQLDatabaseClass GPartsMySQLDatabaseClass;
struct _GPartsMySQLDatabase
{
GObject parent;
};
struct _GPartsMySQLDatabaseClass
{
GObjectClass parent;
};
GType
gparts_mysql_database_get_type(void);
GPartsMySQLDatabase*
gparts_mysql_database_new();

65
src/gparts-mysql-module.c Normal file
View File

@ -0,0 +1,65 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include <gmodule.h>
#include <mysql.h>
#include "gparts-mysql-result.h"
#include "gparts-mysql-database.h"
#include "gparts-database-type.h"
const gchar*
g_module_check_init(GModule *module)
{
g_module_make_resident(module);
g_debug("Hello from indise");
GPARTS_TYPE_MYSQL_DATABASE;
GPARTS_TYPE_MYSQL_RESULT;
return NULL;
}
void
gparts_database_register(GPartsDatabaseType *database_type)
{
GPartsDatabaseTypeClass *database_type_class = GPARTS_DATABASE_TYPE_GET_CLASS(database_type);
if (database_type_class != NULL && database_type_class->add_type != NULL)
{
database_type_class->add_type(
database_type,
"MySQL",
GPARTS_TYPE_MYSQL_DATABASE,
( GPARTS_DATABASE_TYPE_FLAGS_USES_USERNAME |
GPARTS_DATABASE_TYPE_FLAGS_USES_PASSWORD |
GPARTS_DATABASE_TYPE_FLAGS_USES_SERVER |
GPARTS_DATABASE_TYPE_FLAGS_USES_DATABASE
)
);
}
else
{
g_critical("Unable to register MySQL database module");
}
}

394
src/gparts-mysql-result.c Normal file
View File

@ -0,0 +1,394 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include <mysql.h>
#include "gparts-database-result.h"
#include "gparts-mysql-result.h"
/*! \file gparts-mysql-result.c
*
* \brief A wrapper for MySQL database results.
*/
typedef struct _GPartsMySQLResultPrivate GPartsMySQLResultPrivate;
struct _GPartsMySQLResultPrivate
{
MYSQL_RES *result;
};
#define GPARTS_MYSQL_RESULT_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_MYSQL_RESULT, GPartsMySQLResultPrivate)
static void
gparts_mysql_result_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_mysql_result_finalize(GObject *object);
static guint
gparts_mysql_result_get_column_count(GPartsDatabaseResult *result);
static gboolean
gparts_mysql_result_get_column_index(GPartsDatabaseResult *result, const gchar *name, gint *index);
static GType
gparts_mysql_result_get_column_type(GPartsDatabaseResult *result, gint column);
static const gchar*
gparts_mysql_result_get_column_units(GPartsDatabaseResult *result, gint column);
static void
gparts_mysql_result_get_column_value(GPartsDatabaseResult *result, gint column, GValue *value);
static void
gparts_mysql_result_get_field_value(GPartsDatabaseResult *result, gint row, gint column, GValue *value);
static guint
gparts_mysql_result_get_row_count(GPartsDatabaseResult *result);
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_mysql_result_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(
g_class,
sizeof(GPartsMySQLResultPrivate)
);
object_class->finalize = gparts_mysql_result_finalize;
}
/*! \brief Initialize the GPartsDatabaseResult interface.
*
* \param [in] iface The interface to initialize.
*/
static void
gparts_mysql_result_database_init(GPartsDatabaseResultInterface *iface)
{
iface->get_column_count = gparts_mysql_result_get_column_count;
iface->get_column_index = gparts_mysql_result_get_column_index;
iface->get_column_type = gparts_mysql_result_get_column_type;
iface->get_column_units = gparts_mysql_result_get_column_units;
iface->get_column_value = gparts_mysql_result_get_column_value;
iface->get_field_value = gparts_mysql_result_get_field_value;
iface->get_row_count = gparts_mysql_result_get_row_count;
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_mysql_result_finalize(GObject *object)
{
g_debug("gparts_mysql_result_finalize");
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(object);
mysql_free_result(private->result);
}
/*! \brief Gets the number of columns in the database result.
*
* \param [in] result The database result.
* \return The number of columns in the database result.
*/
static guint
gparts_mysql_result_get_column_count(GPartsDatabaseResult *result)
{
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
return mysql_num_fields(private->result);
}
/*! \brief Untested WIP.
*/
static gboolean
gparts_mysql_result_get_column_index(GPartsDatabaseResult *result, const gchar *name, gint *index)
{
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
gint index0;
gint column_count = mysql_num_fields(private->result);
MYSQL_FIELD *columns = mysql_fetch_fields(private->result);
for (index0=0; index0<column_count; index0++)
{
if (g_strcmp0(columns[index0].name, name) == 0)
{
*index = index0;
return TRUE;
}
}
return FALSE;
}
/*! \brief Gets the type of a column.
*
* With an invalid column index, this function returns G_TYPE_INVALID.
*
* \param [in] result The database result.
* \param [in] column The zero-based index of the column.
* \return The GType of the fileds in the column.
*/
static GType
gparts_mysql_result_get_column_type(GPartsDatabaseResult *result, gint column)
{
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
GType type = G_TYPE_INVALID;
if (column < mysql_num_fields(private->result))
{
MYSQL_FIELD *field = mysql_fetch_field_direct(private->result, column);
switch (field->type)
{
case MYSQL_TYPE_FLOAT:
type = G_TYPE_DOUBLE;
break;
case MYSQL_TYPE_LONG:
type = G_TYPE_INT;
break;
default:
type = G_TYPE_STRING;
}
}
return type;
}
/*! \brief Gets the units for a column.
*
* \param [in] result The database result.
* \param [in] column The zero-based index of the column.
*/
static const gchar*
gparts_mysql_result_get_column_units(GPartsDatabaseResult *result, gint column)
{
/* TODO Temporary code until database gets metadata. */
struct entry
{
const gchar *name;
const gchar *units;
};
struct entry table[] =
{
{ "IF", "AMPS", },
{ "Resistance", "RESISTOR" },
{ "Tolerance", "PERCENT" },
{ "VBR", "VOLTS" },
{ "VZ", "VOLTS" },
{ "VF", "VOLTS" },
{ "VR", "VOLTS" },
{ "VRWM", "VOLTS" },
{ "VZ", "VOLTS" },
{ NULL, "NONE" }
};
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
struct entry *t = &table[0];
const gchar *units = "NONE";
if (column < mysql_num_fields(private->result))
{
MYSQL_FIELD *field = mysql_fetch_field_direct(private->result, column);
while (t->name != NULL && g_strcmp0(t->name, field->name) != 0)
{
t++;
}
units = t->units;
}
return units;
}
/*! \brief Gets the name of a column.
*
* The value must be previously initialized as a G_TYPE_STRING. If an error
* occurs, the value does not get assigned.
*
* \param [in] result The database result.
* \param [in] column The zero-based index of the column.
* \param [out] value The name of the column.
*/
static void
gparts_mysql_result_get_column_value(GPartsDatabaseResult *result, gint column, GValue *value)
{
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
if (column < mysql_num_fields(private->result))
{
MYSQL_FIELD *field = mysql_fetch_field_direct(private->result, column);
g_value_set_string(value, field->name);
}
}
/*! \brief Gets the value of a field.
*
* This function initializes and sets value to the contents of the field. The
* value parameter must not be initialized (just filled with zeros). If this
* function encounters an error, the value remains unset.
*
* \param [in] result The database result.
* \param [in] row The zero based index of the row.
* \param [in] column The zero based index of the column.
* \param [out] value The value of the field.
*/
static void
gparts_mysql_result_get_field_value(GPartsDatabaseResult *result, gint row, gint column, GValue *value)
{
GPartsMySQLResultPrivate *private;
MYSQL_ROW data;
g_return_if_fail(result != NULL);
g_return_if_fail(column >= 0);
g_return_if_fail(row >= 0);
g_return_if_fail(value != NULL);
private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
g_return_if_fail(column < mysql_num_fields(private->result));
mysql_data_seek(private->result, row);
data = mysql_fetch_row(private->result);
if (data != NULL && data[column] != NULL)
{
gulong length = *(mysql_fetch_lengths(private->result) + column);
gchar *string = g_strndup(data[column], length);
GType type = gparts_mysql_result_get_column_type(result, column);
if (type == G_TYPE_DOUBLE)
{
g_value_init(value, G_TYPE_DOUBLE);
g_value_set_double(value, g_ascii_strtod(string, NULL));
g_free(string);
}
else if (type == G_TYPE_INT)
{
g_value_init(value, G_TYPE_INT);
g_value_set_int(value, g_ascii_strtoll(string, NULL, 10));
g_free(string);
}
else
{
g_value_init(value, G_TYPE_STRING);
g_value_take_string(value, string);
}
}
}
/*! \brief Gets the number of rows in the database result.
*
* \param [in] result The database result.
* \return The number of rows in the database result.
*/
static guint
gparts_mysql_result_get_row_count(GPartsDatabaseResult *result)
{
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(result);
return mysql_num_rows(private->result);
}
/*! \brief Gets the GType of the GPartsMySQLResult class.
*
* \return The GType of the GPartsMySQLResult class.
*/
GType
gparts_mysql_result_get_type(void)
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsMySQLResultClass),
NULL,
NULL,
gparts_mysql_result_class_init,
NULL,
NULL,
sizeof(GPartsMySQLResult),
0,
NULL,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_mysql_result_database_init,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-mysql-result",
&tinfo,
0
);
g_type_add_interface_static(
type,
GPARTS_TYPE_DATABASE_RESULT,
&iinfo
);
}
return type;
}
/*! \brief Create a new GPartsMySQLResult
*
* \param [in] result The MySQL result.
* \return A new GPartsMySQLResult.
*/
GPartsMySQLResult*
gparts_mysql_result_new(MYSQL_RES *result)
{
GPartsMySQLResult *r = g_object_new(GPARTS_TYPE_MYSQL_RESULT, NULL);
GPartsMySQLResultPrivate *private = GPARTS_MYSQL_RESULT_GET_PRIVATE(r);
private->result = result;
return r;
}

47
src/gparts-mysql-result.h Normal file
View File

@ -0,0 +1,47 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#define GPARTS_TYPE_MYSQL_RESULT (gparts_mysql_result_get_type())
#define GPARTS_MYSQL_RESULT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_MYSQL_RESULT,GPARTSMySQLResult))
#define GPARTS_MYSQL_RESULT_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_MYSQL_RESULT,GPARTSMySQLResultClass))
#define GPARTS_IS_MYSQL_RESULT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_MYSQL_RESULT))
#define GPARTS_IS_MYSQL_RESULT_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_MYSQL_RESULT))
#define GPARTS_MYSQL_RESULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_MYSQL_RESULT,GPARTSMySQLResultClass))
typedef struct _GPartsMySQLResult GPartsMySQLResult;
typedef struct _GPartsMySQLResultClass GPartsMySQLResultClass;
struct _GPartsMySQLResult
{
GObject parent;
};
struct _GPartsMySQLResultClass
{
GObjectClass parent;
};
GType
gparts_mysql_result_get_type(void);
GPartsMySQLResult*
gparts_mysql_result_new(MYSQL_RES *result);

120
src/gparts-object-list.c Normal file
View File

@ -0,0 +1,120 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-object-list.h"
#define GPARTS_OBJECT_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GPARTS_TYPE_OBJECT_LIST,GPartsObjectListPrivate))
typedef struct _GPartsObjectListPrivate GPartsObjectListPrivate;
struct _GPartsObjectListPrivate
{
GSList *objects;
};
static void
gparts_object_list_add_child(GtkBuildable *buildable, GtkBuilder *builder, GObject *object, const gchar *type);
static void
gparts_object_list_buildable_init(gpointer g_iface, gpointer g_iface_data);
static void
gparts_object_list_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_object_list_dispose(GObject *object);
static void
gparts_object_list_add_child(GtkBuildable *buildable, GtkBuilder *builder, GObject *object, const gchar *type)
{
GPartsObjectListPrivate *privat = GPARTS_OBJECT_LIST_GET_PRIVATE(buildable);
privat->objects = g_slist_append(privat->objects, object);
}
static void
gparts_object_list_buildable_init(gpointer g_iface, gpointer g_iface_data)
{
GtkBuildableIface *iface = (GtkBuildableIface*) g_iface;
iface->add_child = gparts_object_list_add_child;
}
static void
gparts_object_list_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass *object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(object_class, sizeof(GPartsObjectListPrivate));
object_class->dispose = gparts_object_list_dispose;
}
static void
gparts_object_list_dispose(GObject *object)
{
GPartsObjectListPrivate *privat = GPARTS_OBJECT_LIST_GET_PRIVATE(object);
g_slist_foreach(privat->objects, g_object_unref, NULL);
g_slist_free(privat->objects);
privat->objects = NULL;
}
GType
gparts_object_list_get_type(void)
{
static GType type = G_TYPE_INVALID;
if (type == G_TYPE_INVALID)
{
static const GTypeInfo tinfo = {
sizeof(GPartsObjectListClass), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
gparts_object_list_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof(GPartsObjectList), /* instance_size */
0, /* n_preallocs */
NULL, /* instance_init */
NULL /* value_table */
};
static const GInterfaceInfo iinfo = {
gparts_object_list_buildable_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
type = g_type_register_static(
G_TYPE_OBJECT,
"GPartsObjectList",
&tinfo,
0
);
g_type_add_interface_static(type, GTK_TYPE_BUILDABLE, &iinfo);
}
return type;
}

48
src/gparts-object-list.h Normal file
View File

@ -0,0 +1,48 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-object-list.h
*
* \brief Stores a buildable list of GObjects
*/
#define GPARTS_TYPE_OBJECT_LIST (gparts_object_list_get_type())
#define GPARTS_OBJECT_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_OBJECT_LIST,GPartsObjectList))
#define GPARTS_OBJECT_LIST_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_OBJECT_LIST,GPartsObjectListClass))
#define GPARTS_IS_OBJECT_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_OBJECT_LIST))
#define GPARTS_IS_OBJECT_LIST_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_OBJECT_LIST))
#define GPARTS_OBJECT_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_OBJECT_LIST,GPartsObjectListClass))
typedef struct _GPartsObjectList GPartsObjectList;
typedef struct _GPartsObjectListClass GPartsObjectListClass;
struct _GPartsObjectList
{
GObject parent;
};
struct _GPartsObjectListClass
{
GObjectClass parent;
};
GType
gparts_object_list_get_type(void);

56
src/gparts-popup.c Normal file
View File

@ -0,0 +1,56 @@
static void
popup(GtkWidget *widget, gpointer user_data)
{
GtkTreeViewColumn *column;
gint index = 0;
GtkMenu *menu = gtk_menu_new();
privat = GET_PRIVATE(widget);
g_signal_connect(
menu,
"deactivate",
G_CALLBACK(gtk_widget_destroy),
NULL
);
column = gtk_tree_view_get_column(tree_view, index++);
while (column != NULL)
{
GtkCheckMenuItem *item;
item = gtk_check_menu_item_new_with_label(gtk_tree_view_column_get_title(column));
g_object_set(
item,
"active", gtk_tree_view_column_get_visible(column),
NULL
);
g_signal_connect(
item,
"toggled",
G_CALLBACK(),
);
column = gtk_tree_view_get_column(tree_view, index++);
}
gtk_menu_attach_to_widget(widget);
gtk_menu_popup(
menu,
NULL,
NULL,
NULL,
NULL,
0,
gtk_get_current_event_time()
);
}

View File

View File

@ -0,0 +1,46 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-postgresql-database.h
*/
#define GPARTS_TYPE_POSTGRESQL_DATABASE (gparts_postgresql_database_get_type())
#define GPARTS_POSTGRESQL_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_POSTGRESQL_DATABASE,GPARTSPostgreSQLDatabase))
#define GPARTS_POSTGRESQL_DATABASE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_POSTGRESQL_DATABASE,GPARTSPostgreSQLDatabaseClass))
#define GPARTS_IS_POSTGRESQL_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_POSTGRESQL_DATABASE))
#define GPARTS_IS_POSTGRESQL_DATABASE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_POSTGRESQL_DATABASE))
#define GPARTS_POSTGRESQL_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_POSTGRESQL_DATABASE,GPARTSPostgreSQLDatabaseClass))
typedef struct _GPartsPostgreSQLDatabase GPartsPostgreSQLDatabase;
typedef struct _GPartsPostgreSQLDatabaseClass GPartsPostgreSQLDatabaseClass;
struct _GPartsPostgreSQLDatabase
{
GObject parent;
};
struct _GPartsPostgreSQLDatabaseClass
{
GObjectClass parent;
};
GType
gparts_postgresql_database_get_type(void);

View File

@ -0,0 +1,43 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include <gmodule.h>
#include <libpq-fe.h>
#include "gparts-pg-result.h"
#include "gparts-pg-database.h"
const gchar*
g_module_check_init(GModule *module)
{
g_module_make_resident(module);
//GPARTS_TYPE_PG_DATABASE;
//GPARTS_TYPE_PG_RESULT;
return NULL;
}
void
gparts_database_register()
{
}

View File

View File

@ -0,0 +1,46 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-postgresql-result.h
*/
#define GPARTS_TYPE_POSTGRESQL_RESULT (gparts_postgresql_result_get_type())
#define GPARTS_POSTGRESQL_RESULT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_POSTGRESQL_RESULT,GPARTSPostgreSQLResult))
#define GPARTS_POSTGRESQL_RESULT_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_POSTGRESQL_RESULT,GPARTSPostgreSQLResultClass))
#define GPARTS_IS_POSTGRESQL_RESULT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_POSTGRESQL_RESULT))
#define GPARTS_IS_POSTGRESQL_RESULT_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_POSTGRESQL_RESULT))
#define GPARTS_POSTGRESQL_RESULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_POSTGRESQL_RESULT,GPARTSPostgreSQLResultClass))
typedef struct _GPartsPostgreSQLResult GPartsPostgreSQLResult;
typedef struct _GPartsPostgreSQLResultClass GPartsPostgreSQLResultClass;
struct _GPartsPostgreSQLResult
{
GObject parent;
};
struct _GPartsPostgreSQLResultClass
{
GObjectClass parent;
};
GType
gparts_postgresql_result_get_type(void);

323
src/gparts-preview-ctrl.c Normal file
View File

@ -0,0 +1,323 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-preview-ctrl.h"
enum
{
GPARTS_PREVIEW_CTRL_PROPID_COPY_ACTION = 1,
GPARTS_PREVIEW_CTRL_PROPID_SYMBOL_SOURCE,
GPARTS_PREVIEW_CTRL_PROPID_TARGET,
};
typedef struct _GPartsPreviewCtrlPrivate GPartsPreviewCtrlPrivate;
struct _GPartsPreviewCtrlPrivate
{
GtkAction *copy_action;
GtkTreeView *symbol_source;
GtkDrawingArea *target;
};
#define GPARTS_PREVIEW_CTRL_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_PREVIEW_CTRL,GPartsPreviewCtrlPrivate)
static gchar*
gparts_preview_ctrl_build(GPartsPreviewCtrl *controller);
static void
gparts_preview_ctrl_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_preview_ctrl_dispose(GObject *object);
static void
gparts_preview_ctrl_finalize(GObject *object);
static void
gparts_preview_ctrl_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_preview_ctrl_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_preview_ctrl_set_result(GPartsPreviewCtrl *query, GPartsDatabaseResult *result);
/**** Signal handlers ****/
static void
gparts_preview_ctrl_copy_action_cb(GtkAction *action, GPartsPreviewCtrl *preview_ctrl);
static void
gparts_preview_ctrl_show_cb(GtkWidget *widget, GPartsPreviewCtrl *controller);
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_preview_ctrl_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsPreviewCtrlPrivate));
object_class->dispose = gparts_preview_ctrl_dispose;
object_class->finalize = gparts_preview_ctrl_finalize;
object_class->get_property = gparts_preview_ctrl_get_property;
object_class->set_property = gparts_preview_ctrl_set_property;
g_object_class_install_property(
object_class,
GPARTS_PREVIEW_CTRL_PROPID_COPY_ACTION,
g_param_spec_object(
"copy-action",
"",
"",
GTK_TYPE_ACTION,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_PREVIEW_CTRL_PROPID_SYMBOL_SOURCE,
g_param_spec_object(
"symbol-source",
"",
"",
G_TYPE_OBJECT,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
object_class,
GPARTS_PREVIEW_CTRL_PROPID_TARGET,
g_param_spec_object(
"target",
"",
"",
GTK_TYPE_DRAWING_AREA,
G_PARAM_READWRITE
)
);
}
static void
gparts_preview_ctrl_copy_action_cb(GtkAction *action, GPartsPreviewCtrl *preview_ctrl)
{
}
static void
gparts_preview_ctrl_dispose(GObject *object)
{
//gparts_preview_ctrl_set_database(object, NULL);
//gparts_preview_ctrl_set_target(object, NULL);
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_preview_ctrl_finalize(GObject *object)
{
g_debug("gparts_preview_ctrl_finalize");
GPartsPreviewCtrlPrivate *private = GPARTS_PREVIEW_CTRL_GET_PRIVATE(object);
}
static void
gparts_preview_ctrl_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
}
GType
gparts_preview_ctrl_get_type(void)
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsPreviewCtrlClass),
NULL,
NULL,
gparts_preview_ctrl_class_init,
NULL,
NULL,
sizeof(GPartsPreviewCtrl),
0,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-view-controller",
&tinfo,
0
);
}
return type;
}
GPartsPreviewCtrl*
gparts_preview_ctrl_new()
{
}
static void
gparts_preview_ctrl_show_cb(GtkWidget *widget, GPartsPreviewCtrl *preview_ctrl)
{
}
static void
gparts_preview_ctrl_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
GPartsPreviewCtrl *preview_ctrl = GPARTS_PREVIEW_CTRL(object);
switch (property_id)
{
case GPARTS_PREVIEW_CTRL_PROPID_COPY_ACTION:
gparts_preview_ctrl_set_copy_action(preview_ctrl, g_value_get_object(value));
break;
case GPARTS_PREVIEW_CTRL_PROPID_SYMBOL_SOURCE:
gparts_preview_ctrl_set_symbol_source(preview_ctrl, g_value_get_object(value));
break;
case GPARTS_PREVIEW_CTRL_PROPID_TARGET:
gparts_preview_ctrl_set_target(preview_ctrl, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
void
gparts_preview_ctrl_set_copy_action(GPartsPreviewCtrl *preview_ctrl, GtkAction *action)
{
GPartsPreviewCtrlPrivate *privat = GPARTS_PREVIEW_CTRL_GET_PRIVATE(preview_ctrl);
if (privat->copy_action != action)
{
if (privat->copy_action != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->copy_action,
G_CALLBACK(gparts_preview_ctrl_copy_action_cb),
preview_ctrl
);
g_object_unref(privat->copy_action);
}
privat->copy_action = action;
if (privat->copy_action != NULL)
{
g_object_ref(privat->copy_action);
g_signal_connect(
privat->copy_action,
"activate",
G_CALLBACK(gparts_preview_ctrl_copy_action_cb),
preview_ctrl
);
//gtk_action_set_sensitive(privat->copy_action, (privat->database != NULL));
}
g_object_notify(G_OBJECT(preview_ctrl), "copy-action");
}
}
void
gparts_preview_ctrl_set_symbol_source(GPartsPreviewCtrl *preview_ctrl, GtkTreeView *symbol_source)
{
GPartsPreviewCtrlPrivate *privat = GPARTS_PREVIEW_CTRL_GET_PRIVATE(preview_ctrl);
if (privat->symbol_source = symbol_source)
{
if (privat->symbol_source != NULL)
{
g_object_unref(privat->symbol_source);
}
privat->symbol_source = symbol_source;
if (privat->symbol_source != NULL)
{
g_object_ref(privat->symbol_source);
}
g_object_notify(G_OBJECT(preview_ctrl), "symbol-source");
}
}
void
gparts_preview_ctrl_set_target(GPartsPreviewCtrl *preview_ctrl, GtkDrawingArea *target)
{
GPartsPreviewCtrlPrivate *privat = GPARTS_PREVIEW_CTRL_GET_PRIVATE(preview_ctrl);
if (privat->target != target)
{
if (privat->target != NULL)
{
g_signal_handlers_disconnect_by_func(
privat->target,
G_CALLBACK(gparts_preview_ctrl_show_cb),
preview_ctrl
);
g_object_unref(privat->target);
}
privat->target = target;
if (privat->target != NULL)
{
g_object_ref(privat->target);
g_signal_connect(
privat->target,
"show",
G_CALLBACK(gparts_preview_ctrl_show_cb),
preview_ctrl
);
}
g_object_notify(G_OBJECT(preview_ctrl), "target");
}
}

78
src/gparts-preview-ctrl.h Normal file
View File

@ -0,0 +1,78 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-preview-ctrl.h
*/
#define GPARTS_TYPE_PREVIEW_CTRL (gparts_preview_ctrl_get_type())
#define GPARTS_PREVIEW_CTRL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_PREVIEW_CTRL,GPartsPreviewCtrl))
#define GPARTS_PREVIEW_CTRL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_PREVIEW_CTRL,GPartsPreviewCtrlClass))
#define GPARTS_IS_PREVIEW_CTRL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_PREVIEW_CTRL))
#define GPARTS_IS_PREVIEW_CTRL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_PREVIEW_CTRL))
#define GPARTS_PREVIEW_CTRL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_PREVIEW_CTRL,GPartsPreviewCtrlClass))
typedef struct _GPartsPreviewCtrl GPartsPreviewCtrl;
typedef struct _GPartsPreviewCtrlClass GPartsPreviewCtrlClass;
struct _GPartsPreviewCtrl
{
GObject parent;
};
struct _GPartsPreviewCtrlClass
{
GObjectClass parent;
};
GType
gparts_preview_ctrl_get_type(void);
GPartsPreviewCtrl*
gparts_preview_ctrl_new();
/*! \brief Sets the action.
*
* Sets the action to copy the symbol to the clipboard.
*
* \param [in] preview_ctrl The controller.
* \param [in] database The action to to copy the symbol to the clipboard.
*/
void
gparts_preview_ctrl_set_copy_action(GPartsPreviewCtrl *preview_ctrl, GtkAction *action);
/*! \brief Sets the source view for data used by field expansion.
*
* If this controller does not use field expansion for any operations, then
* the source may be set to NULL.
*
* \param [in] preview_ctrl The controller.
* \param [in] source
*/
void
gparts_preview_ctrl_set_symbol_source(GPartsPreviewCtrl *preview_ctrl, GtkTreeView *soruce);
/*! \brief Sets the target view for results from database queries.
*
* \param [in] preview_ctrl The controller.
* \param [in] target A GtkTreeView to place database query results into.
*/
void
gparts_preview_ctrl_set_target(GPartsPreviewCtrl *preview_ctrl, GtkDrawingArea *target);

239
src/gparts-preview.c Normal file
View File

@ -0,0 +1,239 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-preview.c
*
* \brief A widget to preview schematic symbols.
*/
#include <gtk/gtk.h>
#include "gparts-preview.h"
typedef struct _GPartsPreviewPrivate GPartsPreviewPrivate;
struct _GPartsPreviewPrivate
{
};
#define GPARTS_PREVIEW_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object, GPARTS_TYPE_PREVIEW, GPartsPreviewPrivate)
static void
gparts_preview_instance_init(GTypeInstance* instance, gpointer g_class);
static void
gparts_preview_buildable_init(GtkBuildableIface *iface);
static void
gparts_preview_dispose(GObject* object);
static void
gparts_preview_finalize(GObject* object);
static void
gparts_preview_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec);
static void
gparts_preview_set_buildable_property(GtkBuildable *buildable, GtkBuilder *builder, const gchar *name, const GValue *value);
static void
gparts_preview_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec);
/*! \brief Initialize class data.
*
* \param [in] g_class
* \param [in] g_class_data
*/
static void
gparts_preview_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(
g_class,
sizeof(GPartsPreviewPrivate)
);
object_class->dispose = gparts_preview_dispose;
object_class->finalize = gparts_preview_finalize;
object_class->get_property = gparts_preview_get_property;
object_class->set_property = gparts_preview_set_property;
}
/** \brief Unreference all referenced objects.
*
* This function provides the first stage of object destruction.
*
* \param [in] object The object to dispose.
*/
static void
gparts_preview_dispose(GObject *object)
{
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_preview_finalize(GObject *object)
{
}
/*! \brief
*
*
*
*
*/
static void
gparts_preview_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsPreviewPrivate *private = GPARTS_PREVIEW_GET_PRIVATE(object);
/* TODO handle case where private is NULL */
switch ( property_id )
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief
*
*
*
*
*/
GType
gparts_preview_get_type( void )
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsPreviewClass),
NULL,
NULL,
gparts_preview_class_init,
NULL,
NULL,
sizeof(GPartsPreview),
0,
gparts_preview_instance_init,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_preview_buildable_init,
NULL,
NULL
};
type = g_type_register_static(
GTK_TYPE_BIN,
"gparts-preview",
&tinfo,
0
);
g_type_add_interface_static(
type,
GTK_TYPE_BUILDABLE,
&iinfo
);
}
return type;
}
/*! \brief Initialize instance data.
*
* \param instance
* \param g_class
*/
static void
gparts_preview_instance_init(GTypeInstance* instance, gpointer g_class)
{
GPartsPreviewPrivate *private = GPARTS_PREVIEW_GET_PRIVATE(instance);
// GdkColor color = { 0, 0, 0, 0 };
// gtk_widget_modify_bg(
// instance,
// GTK_STATE_NORMAL,
// &color
// );
// gtk_widget_modify_fg(
// instance,
// GTK_STATE_NORMAL,
// &color
// );
// GtkBin *bin = GTK_BIN(instance);
// bin = gtk_moz_embed_new();
}
static void
gparts_preview_set_buildable_property(GtkBuildable *buildable, GtkBuilder *builder, const gchar *name, const GValue *value)
{
{
GtkBuildableIface *iface = GTK_BUILDABLE_GET_IFACE(buildable);
GtkBuildableIface *parent = g_type_interface_peek_parent(iface);
parent->set_buildable_property(buildable, builder, name, value);
}
}
/*! \brief
*
*
*
*
*/
static void
gparts_preview_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
GPartsPreviewPrivate *private = GPARTS_PREVIEW_GET_PRIVATE(object);
switch ( property_id )
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief
*
*
*
*/
static void
gparts_preview_buildable_init(GtkBuildableIface *iface)
{
iface->set_buildable_property = gparts_preview_set_buildable_property;
}

46
src/gparts-preview.h Normal file
View File

@ -0,0 +1,46 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#define GPARTS_TYPE_PREVIEW (gparts_preview_get_type())
#define GPARTS_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_PREVIEW,GPartsPreview))
#define GPARTS_PREVIEW_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_PREVIEW,GPartsPreviewClass))
#define GPARTS_IS_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_PREVIEW))
#define GPARTS_IS_PREVIEW_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_PREVIEW))
#define GPARTS_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_PREVIEW,GPartsPreviewClass))
typedef struct _GPartsPreview GPartsPreview;
typedef struct _GPartsPreviewClass GPartsPreviewClass;
struct _GPartsPreview
{
GtkTreeView parent;
};
struct _GPartsPreviewClass
{
GtkTreeViewClass parent;
};
GType
gparts_preview_get_type(void);
GPartsPreview*
gparts_preview_new(void);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-result-controller.h
*
* \brief A controller for syncronizing database views and GUI views.
*
* GtkTreeViews do not handle multiple changes well. So, when changes occur
* to the model's data, the controller creates an new model and places it in
* the GUI view. The old model gets disposed.
*
* \note
* When making multiple changes to the properties of this controller, some
* combinations of values may produce errors. To prevent the GUI view from
* getting refreshed with properties that are out-of-sync, temporarily set one
* of the properties to NULL. This value will prevent the view from getting
* refreshed. After makeing all the other property changes, set the NULL
* property back to a valid value.
*/
#define GPARTS_TYPE_RESULT_CONTROLLER (gparts_result_controller_get_type())
#define GPARTS_RESULT_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_RESULT_CONTROLLER,GPartsResultController))
#define GPARTS_RESULT_CONTROLLER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_RESULT_CONTROLLER,GPartsResultControllerClass))
#define GPARTS_IS_RESULT_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_RESULT_CONTROLLER))
#define GPARTS_IS_RESULT_CONTROLLER_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_RESULT_CONTROLLER))
#define GPARTS_RESULT_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_RESULT_CONTROLLER,GPartsResultControllerClass))
typedef struct _GPartsResultController GPartsResultController;
typedef struct _GPartsResultControllerClass GPartsResultControllerClass;
struct _GPartsResultController
{
GObject parent;
};
struct _GPartsResultControllerClass
{
GObjectClass parent;
};
GType
gparts_result_controller_get_type(void);
void
gparts_result_controller_refresh(GPartsResultController *controller);
void
gparts_result_controller_set_customize_ctrl(GPartsResultController *controller, GPartsCustomizeCtrl *customize_ctrl);
/*! \brief Sets the database.
*
* Sets the database to use for subsequent database operations.
*
* \param [in] controller The controller.
* \param [in] database The database to use for subsequent operations.
*/
void
gparts_result_controller_set_database_ctrl(GPartsResultController *controller, GPartsLoginCtrl *database);
/*! \brief Sets the source view for data used by field expansion.
*
* If this controller does not use field expansion for any operations, then
* the source may be set to NULL.
*
* \param [in] controller The controller.
* \param [in] source
*/
void
gparts_result_controller_set_source(GPartsResultController *controller, GObject *soruce);
/*! \brief Sets the target view for results from database queries.
*
* \param [in] controller The controller.
* \param [in] target A GtkTreeView to place database query results into.
*/
void
gparts_result_controller_set_target(GPartsResultController *controller, GtkTreeView *target);
/*! \brief Sets the SQL template string for database queries.
*
* This property contains the SQL statement to execute for database queries.
*
* If the SQL statement depends on data from the selection in another view,
* then the source property must be set to the view that contains the data.
* The column names of the data must be placed within the statement with
* delimiters: $(column_name).
*
* Until the expansion logic gets more sophisticated, the name of the database
* view within the statement must be %s, just as the printf format.
*
* \param [in] controller The controller.
* \param [in] template The SQL template string.
*/
void
gparts_result_controller_set_template(GPartsResultController *controller, const gchar *template);
/*! \brief Sets the name of the database view.
*
* Sets the name of the database view for this controller's subsequent
* database operations.
*
* If the name of the view depends on data from the source selection, then
* place the column name in delimiters for field expansion: $(column_name).
*
* \param [in] controller The controller.
* \param [in] view_name The name of the view for database operations.
*/
void
gparts_result_controller_set_result_name(GPartsResultController *controller, const gchar *view_name);

744
src/gparts-result-model.c Normal file
View File

@ -0,0 +1,744 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <gtk/gtk.h>
#include "gparts-database-result.h"
#include "gparts-result-model.h"
#include "gparts-units.h"
#define GPARTS_RESULT_MODEL_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_RESULT_MODEL,GPartsResultModelPrivate)
enum
{
GPARTS_RESULT_MODEL_PROPID_RESULT = 1
};
typedef struct _GPartsResultModelPrivate GPartsResultModelPrivate;
struct _GPartsResultModelPrivate
{
GPartsDatabaseResult *result;
gint stamp;
};
static void
gparts_result_model_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_result_model_dispose(GObject *object);
static void
gparts_result_model_finalize(GObject *object);
static GType
gparts_result_model_get_column_type(GtkTreeModel *tree_model, gint index);
static void
gparts_result_model_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static GtkTreeModelFlags
gparts_result_model_get_flags(GtkTreeModel *tree_model);
static gboolean
gparts_result_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path);
static gint
gparts_result_model_get_n_columns(GtkTreeModel *tree_model);
static GtkTreePath*
gparts_result_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter);
static void
gparts_result_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value);
static void
gparts_result_model_instance_init(GTypeInstance *instance, gpointer g_class);
/*static*/ gboolean
gparts_result_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent);
static gboolean
gparts_result_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter);
static gboolean
gparts_result_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter);
static gint
gparts_result_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter);
static gboolean
gparts_result_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n);
static gboolean
gparts_result_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child);
static void
gparts_result_model_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_result_model_set_result(GObject *object, GObject *value);
static void
gparts_result_model_tree_model_init(GtkTreeModelIface *iface);
static void
gparts_result_model_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(
g_class,
sizeof(GPartsResultModelPrivate)
);
object_class->dispose = gparts_result_model_dispose;
object_class->finalize = gparts_result_model_finalize;
object_class->get_property = gparts_result_model_get_property;
object_class->set_property = gparts_result_model_set_property;
g_object_class_install_property(
object_class,
GPARTS_RESULT_MODEL_PROPID_RESULT,
g_param_spec_object(
"result",
"",
"",
G_TYPE_OBJECT,
G_PARAM_READWRITE
)
);
}
static void
gparts_result_model_dispose(GObject *object)
{
g_debug("gparts_result_model_dispose()");
gparts_result_model_set_result(object, NULL);
GObjectClass *parent_class = g_type_class_peek_parent(GPARTS_RESULT_MODEL_GET_CLASS(object));
G_OBJECT_CLASS(parent_class)->dispose(object);
}
static void
gparts_result_model_finalize(GObject *object)
{
g_debug("gparts_result_model_finalize()");
GObjectClass *parent_class = g_type_class_peek_parent(GPARTS_RESULT_MODEL_GET_CLASS(object));
G_OBJECT_CLASS(parent_class)->finalize(object);
}
gboolean
gparts_result_model_get_column_index(GPartsResultModel *result_model, const gchar *name, gint *index)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(result_model);
return gparts_database_result_get_column_index(private->result, name, index);
}
/*! \brief Gets the GType of a given column.
*
* \param [in] tree_model The GPartsResultModel.
* \param [in] index The zero based index of the column.
* \return The column's GType.
*/
static GType
gparts_result_model_get_column_type(GtkTreeModel *tree_model, gint index)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
return gparts_database_result_get_column_type(private->result, index);
}
gchar*
gparts_result_model_get_field(GPartsResultModel *model, GtkTreeIter *iter, const gchar *name)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(model);
gchar *result = NULL;
if (private->result != NULL)
{
gint index;
gboolean success;
success = gparts_database_result_get_column_index(private->result, name, &index);
if (success)
{
gboolean error = FALSE;
GString *buffer = g_string_sized_new(10);
GValue value = {0};
gparts_database_result_get_field_value(
private->result,
GPOINTER_TO_UINT(iter->user_data),
index,
&value
);
/* TODO The following code needs to go elsewhere or use transformations */
if(G_IS_VALUE(&value))
{
if (G_VALUE_HOLDS_STRING(&value))
{
g_string_printf(buffer, "%s", g_value_get_string(&value));
}
else if (G_VALUE_HOLDS_DOUBLE(&value))
{
g_string_printf(buffer, "%f", g_value_get_double(&value));
}
else if (G_VALUE_HOLDS_INT(&value))
{
g_string_printf(buffer, "%d", g_value_get_int(&value));
}
else
{
error = TRUE;
}
result = g_string_free(buffer, error);
}
}
}
return result;
}
/*! \brief
*
*
*
*
*/
static void
gparts_result_model_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(object);
/* TODO handle case where private is NULL */
switch ( property_id )
{
case GPARTS_RESULT_MODEL_PROPID_RESULT:
g_value_set_object(value, private->result);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief Gets this model's GtkTreeModelFlags.
*
* \param [in] tree_model The GPartsResultModel.
* \return This model's GtkTreeModelFlags.
*/
static GtkTreeModelFlags
gparts_result_model_get_flags(GtkTreeModel *tree_model)
{
return GTK_TREE_MODEL_LIST_ONLY;
}
/*! \brief Converts a tree path to a tree iterator.
*
* This function will fail if the path does not refer to a valid node in the
* tree model.
*
* \param [in] tree_model The GPartsResultModel
* \param [out] iter If successful, a GtkTreeIter. Invalid if unsuccessful.
* \param [in] path The GtkTreePath to convert to a GtkTreeIter.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_result_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
gint index = gtk_tree_path_get_indices(path)[0];
guint rows = gparts_database_result_get_row_count(private->result);
if (index < rows)
{
iter->stamp = private->stamp;
iter->user_data = GUINT_TO_POINTER(index);
return TRUE;
}
return FALSE;
}
/*! \brief Returns the number of columns in the tree model.
*
* \param [in] tree_model The GPartsResultModel.
* \param [in] tree_model The given tree model.
* \return The number of columns in the tree model.
*/
static gint
gparts_result_model_get_n_columns(GtkTreeModel *tree_model)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
return gparts_database_result_get_column_count(private->result);
}
/*! \brief Converts a GtkTreeIter to a GtkTreePath.
*
* \param [in] tree_model The GPartsResultModel.
* \param [in] iter The iterator to convert to a tree path.
* \return A GtkTreePath that refers to the same node as the iterator.
*/
static GtkTreePath*
gparts_result_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == private->stamp);
GtkTreePath *tree_path = gtk_tree_path_new();
gtk_tree_path_append_index(tree_path, GPOINTER_TO_INT(iter->user_data));
return tree_path;
}
/*! \brief Register this class's GType.
*
* \return The GType of this class.
*/
GType
gparts_result_model_get_type( void )
{
static GType type = 0;
if ( type == 0 )
{
static const GTypeInfo tinfo = {
sizeof(GPartsResultModelClass),
NULL,
NULL,
gparts_result_model_class_init,
NULL,
NULL,
sizeof(GPartsResultModel),
0,
gparts_result_model_instance_init,
NULL
};
static const GInterfaceInfo iinfo = {
(GInterfaceInitFunc) gparts_result_model_tree_model_init,
NULL,
NULL
};
type = g_type_register_static(
G_TYPE_OBJECT,
"gparts-result-model",
&tinfo,
0
);
g_type_add_interface_static(
type,
GTK_TYPE_TREE_MODEL,
&iinfo
);
}
return type;
}
/*! \brief Get a value from the tree model.
*
* This function turns invalid values into blanks. So, an invalid column or
* row will still result in a valid GValue.
*
* \param [in] tree_model The GPartsResultModel.
* \param [in] iter An iterator referencing the value's row.
* \param [in] column A zero based index of the value's column.
* \param [out] value The value of the cell as a GValue.
*/
static void
gparts_result_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == private->stamp);
gparts_database_result_get_field_value(
private->result,
GPOINTER_TO_UINT(iter->user_data),
column,
value
);
/* Turn uninitialized values into blanks */
if (!G_IS_VALUE(value))
{
g_value_init(value, G_TYPE_STRING);
}
}
/*! \brief Initialize instance data.
*
* \param instance
* \param g_class
*/
static void
gparts_result_model_instance_init(GTypeInstance* instance, gpointer g_class)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(instance);
private->stamp = g_random_int();
}
/*! \brief Gets an iterator to a list's first child.
*
* If the parent is NULL, this function gets an iterator to the first node in
* the root list. Since this model does not implement trees, all other cases
* return FALSE.
*
* \param [in] tree_model The GPartsResultModel.
* \param [out] iter If successful, the first child of parent.
* \param [in] parent The parent node.
* \retval TRUE if successful and iter is valid.
* \retval FALSE if otherwise and the iter will not be valid.
*/
/*static*/ gboolean
gparts_result_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
{
if (parent == NULL)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
iter->stamp = private->stamp;
iter->user_data = GINT_TO_POINTER(0);
return TRUE;
}
return FALSE;
}
/*! \brief Determines if a node has children.
*
* Since this model only handles lists, this function always returns FALSE.
*
* \param [in] tree_model Unused.
* \param [out] iter Unused.
* \return FALSE, always.
*/
static gboolean
gparts_result_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
return FALSE;
}
/*! \brief Get the next node in sequence.
*
* \param [in] tree_model The GPartsResultModel.
* \param [in,out] iter The node on entry. If successful, the next node.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_result_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
guint new_position;
guint old_position;
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
g_assert(iter != NULL);
g_assert(iter->stamp == private->stamp);
old_position = GPOINTER_TO_UINT(iter->user_data);
new_position = old_position + 1;
if (new_position > old_position)
{
guint rows = gparts_database_result_get_row_count(private->result);
if (new_position < rows)
{
iter->user_data = GUINT_TO_POINTER(new_position);
return TRUE;
}
}
return FALSE;
}
/*! \brief Returns the number of children a node contains.
*
* Since this model only handles lists, this function returns 0.
*
* \param [in] tree_model The GPartsResultModel.
* \param [in] iter The given node.
* \return The number of iter's children.
*/
static gint
gparts_result_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
{
gint rows = 0;
if (iter == NULL)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
rows = gparts_database_result_get_row_count(private->result);
}
return rows;
}
/*! \brief Gets an iterator to a node's nth child.
*
* If the parent is NULL, this function gets an iterator to the nth node in
* the root list. Since this model only implements lists, in all other cases,
* this function returns FALSE.
*
* \param [in] tree_model The GPartsResultModel.
* \param [out] iter If successful, the nth child of the parent node.
* \param [in] parent The parent node.
* \param [in] n The zero based index of the child node.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_result_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
{
g_assert(iter != NULL);
if (parent == NULL)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(tree_model);
guint rows = gparts_database_result_get_row_count(private->result);
if (n < rows)
{
iter->stamp = private->stamp;
iter->user_data = GINT_TO_POINTER(n);
return TRUE;
}
}
return FALSE;
}
/*! \brief Obtains the parent node of a child node.
*
* Since this model only implements lists, this function always returns FALSE.
*
* \param [in] tree_model The GPartsResultModel.
* \param [out] iter If successful, the parent node.
* \param [in] child The child node.
* \return TRUE if successful and iter is valid. FALSE if otherwise and the
* iter will not be valid.
*/
static gboolean
gparts_result_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
{
return FALSE;
}
/*! \brief Creates a new GPartsResultModel.
*
* \return A new GPartsResultModel.
*/
GPartsResultModel *
gparts_result_model_new(void)
{
return g_object_new(GPARTS_TYPE_RESULT_MODEL, NULL);
}
/*! \brief Adjusts the GtkTreeView's columns to match the database result.
*
*
*
* \param [in] result
* \param [in] tree_view
*/
void
gparts_result_model_set_columns(GPartsDatabaseResult *result, GtkTreeView *tree_view)
{
gint columns;
GtkTreeViewColumn *column;
gint index;
GValue value = {0};
columns = gparts_database_result_get_column_count(result);
g_value_init(&value, G_TYPE_STRING);
for(index=0; index<columns; index++)
{
GList *list;
column = gtk_tree_view_get_column(tree_view, index);
if (column == NULL)
{
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new();
g_object_set(
column,
"resizable", TRUE,
"reorderable", TRUE,
"sizing", GTK_TREE_VIEW_COLUMN_GROW_ONLY,
NULL
);
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_add_attribute(column, renderer, "text", index);
gtk_tree_view_append_column(tree_view, column);
}
list = gtk_tree_view_column_get_cell_renderers(column);
if (list != NULL)
{
GList *node = g_list_first(list);
while (node != NULL)
{
GType type = gparts_database_result_get_column_type(result, index);
if (type == G_TYPE_STRING)
{
g_object_set(G_OBJECT(node->data), "xalign", 0.0, NULL );
}
else
{
g_object_set(G_OBJECT(node->data), "xalign", 1.0, NULL );
}
gparts_units_attach_cell_data_func(
column,
GTK_CELL_RENDERER(node->data),
index,
gparts_database_result_get_column_units(result, index)
);
node = g_list_next(node);
}
}
g_list_free(list);
gparts_database_result_get_column_value(result, index, &value);
g_object_set_property(G_OBJECT(column), "title", &value);
}
g_value_unset(&value);
/* Delete any additional columns */
column = gtk_tree_view_get_column(tree_view, columns);
while(column != NULL)
{
gtk_tree_view_remove_column(tree_view, column);
column = gtk_tree_view_get_column(tree_view, columns);
}
}
/*! \brief
*
*
*
*
*/
static void
gparts_result_model_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch ( property_id )
{
case GPARTS_RESULT_MODEL_PROPID_RESULT:
gparts_result_model_set_result(object, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
/*! \brief
*
*
*
*
*/
static void
gparts_result_model_set_result(GObject *object, GObject *value)
{
GPartsResultModelPrivate *private = GPARTS_RESULT_MODEL_GET_PRIVATE(object);
if (private->result != NULL)
{
g_object_unref(private->result);
}
private->result = GPARTS_DATABASE_RESULT(value);
if (private->result != NULL)
{
g_object_ref(private->result);
}
}
/*! \brief Initialize the tree model interface.
*
* \param [in] iface A pointer to the tree model interface.
*/
static void
gparts_result_model_tree_model_init(GtkTreeModelIface *iface)
{
iface->get_flags = gparts_result_model_get_flags;
iface->get_n_columns = gparts_result_model_get_n_columns;
iface->get_column_type = gparts_result_model_get_column_type;
iface->get_iter = gparts_result_model_get_iter;
iface->get_path = gparts_result_model_get_path;
iface->get_value = gparts_result_model_get_value;
iface->iter_next = gparts_result_model_iter_next;
iface->iter_children = gparts_result_model_iter_children;
iface->iter_has_child = gparts_result_model_iter_has_child;
iface->iter_n_children = gparts_result_model_iter_n_children;
iface->iter_nth_child = gparts_result_model_iter_nth_child;
iface->iter_parent = gparts_result_model_iter_parent;
}

55
src/gparts-result-model.h Normal file
View File

@ -0,0 +1,55 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#define GPARTS_TYPE_RESULT_MODEL (gparts_result_model_get_type())
#define GPARTS_RESULT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_RESULT_MODEL,GPartsResultModel))
#define GPARTS_RESULT_MODEL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_RESULT_MODEL,GPartsResultModelClass))
#define GPARTS_IS_RESULT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_RESULT_MODEL))
#define GPARTS_IS_RESULT_MODEL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_RESULT_MODEL))
#define GPARTS_RESULT_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_RESULT_MODEL,GPartsResultModelClass))
typedef struct _GPartsResultModel GPartsResultModel;
typedef struct _GPartsResultModelClass GPartsResultModelClass;
struct _GPartsResultModel
{
GObject parent;
};
struct _GPartsResultModelClass
{
GObjectClass parent;
};
GType
gparts_result_model_get_type(void);
GPartsResultModel*
gparts_result_model_new(void);
gboolean
gparts_result_model_get_column_index(GPartsResultModel *result_model, const gchar *name, gint *index);
gchar*
gparts_result_model_get_field(GPartsResultModel *model, GtkTreeIter *iter, const gchar *name);
void
gparts_result_model_set_columns(GPartsDatabaseResult *result, GtkTreeView *tree_view);

270
src/gparts-result-view.c Normal file
View File

@ -0,0 +1,270 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <string.h>
#include <gtk/gtk.h>
#include "gparts-database-result.h"
#include "gparts-database.h"
#include "gparts-result-model.h"
#include "gparts-result-view.h"
#define GPARTS_RESULT_VIEW_GET_PRIVATE(object) G_TYPE_INSTANCE_GET_PRIVATE(object,GPARTS_TYPE_RESULT_VIEW,GPartsResultViewPrivate)
enum
{
GPARTS_RESULT_VIEW_PROPID_DATABASE_CONTROLLER = 1,
GPARTS_RESULT_VIEW_PROPID_SOURCE,
GPARTS_RESULT_VIEW_PROPID_TARGET,
GPARTS_RESULT_VIEW_PROPID_TEMPLATE,
GPARTS_RESULT_VIEW_PROPID_RESULT_NAME
};
typedef struct _GPartsResultViewPrivate GPartsResultViewPrivate;
struct _GPartsResultViewPrivate
{
gint sort_order;
};
static gchar*
gparts_result_view_build(GPartsResultView *controller);
static void
gparts_result_view_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_result_view_connect_columns(GPartsResultView *controller);
static void
gparts_result_view_database_controller_notify_cb(GPartsDatabase *database, GParamSpec *pspec, GPartsResultView *controller);
static void
gparts_result_view_disconnect_columns(GPartsResultView *controller);
static void
gparts_result_view_dispose(GObject *object);
static void
gparts_result_view_finalize(GObject *object);
static void
gparts_result_view_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_result_view_set_sort_indicators(GPartsResultView *controller);
static void
gparts_result_view_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_result_view_set_result(GPartsResultView *query, GPartsDatabaseResult *result);
/**** Signal handlers ****/
static void
gparts_result_view_changed_cb(GtkTreeSelection *selection, GPartsResultView *controller);
static void
gparts_result_view_column_clicked_cb(GtkTreeViewColumn *column, gpointer user_data);
static void
gparts_result_view_database_controller_notify_cb(GPartsDatabase *database, GParamSpec *pspec, GPartsResultView *controller);
static void
gparts_result_view_refresh_cb(gpointer unknown, GPartsResultView *controller);
static void
gparts_result_view_show_cb(GtkWidget *widget, GPartsResultView *controller);
/* This signal handler responds to changes in this controller's tree view
* selection. It emits the update signal so other controllers monitoring
* this controller can update themselves.
*/
static void
gparts_result_view_changed_cb(GtkTreeSelection *widget, GPartsResultView *controller)
{
g_signal_emit_by_name(controller, "updated");
}
static void
gparts_result_view_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass* object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(g_class, sizeof(GPartsResultViewPrivate));
object_class->dispose = gparts_result_view_dispose;
object_class->finalize = gparts_result_view_finalize;
// object_class->get_property = gparts_result_view_get_property;
// object_class->set_property = gparts_result_view_set_property;
}
static void
gparts_result_view_column_clicked_cb(GtkTreeViewColumn *column, gpointer user_data)
{
}
#if 0
/* Unsolved Mystery
* The column sort indicator and sort order do not appear in the GUI when set
* inside this function.
*/
static void
gparts_result_view_connect_columns(GPartsResultView *controller)
{
GtkTreeViewColumn *column;
gint index = 0;
GPartsResultViewPrivate *privat = GPARTS_RESULT_VIEW_GET_PRIVATE(controller);
column = gtk_tree_view_get_column(privat->target, index++);
while (column != NULL)
{
gtk_tree_view_column_set_clickable(column, TRUE);
g_signal_connect(
column,
"clicked",
G_CALLBACK(gparts_result_view_column_clicked_cb),
controller
);
column = gtk_tree_view_get_column(privat->target, index++);
}
}
static void
gparts_result_view_disconnect_columns(GPartsResultView *controller)
{
GtkTreeViewColumn *column;
gint index = 0;
GPartsResultViewPrivate *privat = GPARTS_RESULT_VIEW_GET_PRIVATE(controller);
column = gtk_tree_view_get_column(privat->target, index++);
while (column != NULL)
{
g_signal_handlers_disconnect_by_func(
column,
G_CALLBACK(gparts_result_view_column_clicked_cb),
controller
);
column = gtk_tree_view_get_column(privat->target, index++);
}
}
#endif
static void
gparts_result_view_dispose(GObject *object)
{
// GPartsResultView *controller = GPARTS_RESULT_VIEW(object);
// gparts_result_view_set_database_controller(controller, NULL);
// gparts_result_view_set_target(controller, NULL);
}
/*! \brief Deallocate all resources.
*
* This function performs the second and last stage of object destruction.
*
* \param [in] object The object to finalize.
*/
static void
gparts_result_view_finalize(GObject *object)
{
// GPartsResultViewPrivate *private = GPARTS_RESULT_VIEW_GET_PRIVATE(object);
// g_free(private->template);
// g_free(private->view_name);
}
#if 0
static gchar*
gparts_result_view_get_field(GPartsController *controller, const gchar *name)
{
GtkTreeIter iter;
GtkTreeModel *model;
GPartsResultViewPrivate *privat = GPARTS_RESULT_VIEW_GET_PRIVATE(controller);
gboolean success;
gchar *value = NULL;
success = gtk_tree_selection_get_selected(privat->selection, &model, &iter);
if (success && GPARTS_IS_RESULT_MODEL(model))
{
value = gparts_result_model_get_field(GPARTS_RESULT_MODEL(model), &iter, name);
}
return value;
}
#endif
GType
gparts_result_view_get_type(void)
{
static GType type = G_TYPE_INVALID;
if (type == G_TYPE_INVALID)
{
static const GTypeInfo tinfo = {
sizeof(GPartsResultViewClass), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
gparts_result_view_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof(GPartsResultView), /* instance_size */
0, /* n_preallocs */
NULL, /* instance_init */
NULL /* value_table */
};
static const GInterfaceInfo iinfo = {
NULL, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
type = g_type_register_static(
GTK_TYPE_TREE_VIEW,
"GPartsResultView",
&tinfo,
0
);
g_type_add_interface_static(type, GTK_TYPE_BUILDABLE, &iinfo);
}
return type;
}
#if 0
static void
gparts_result_view_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
}
static void
gparts_result_view_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
}
#endif

46
src/gparts-result-view.h Normal file
View File

@ -0,0 +1,46 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-result-view.h
*/
#define GPARTS_TYPE_RESULT_VIEW (gparts_result_view_get_type())
#define GPARTS_RESULT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_RESULT_VIEW,GPartsResultView))
#define GPARTS_RESULT_VIEW_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_RESULT_VIEW,GPartsResultViewClass))
#define GPARTS_IS_RESULT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_RESULT_VIEW))
#define GPARTS_IS_RESULT_VIEW_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_RESULT_VIEW))
#define GPARTS_RESULT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_RESULT_VIEW,GPartsResultViewClass))
typedef struct _GPartsResultView GPartsResultView;
typedef struct _GPartsResultViewClass GPartsResultViewClass;
struct _GPartsResultView
{
GtkTreeView parent;
};
struct _GPartsResultViewClass
{
GtkTreeViewClass parent;
};
GType
gparts_result_view_get_type(void);

165
src/gparts-state.c Normal file
View File

@ -0,0 +1,165 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <glib-object.h>
#include "gparts-state.h"
#define GPARTS_STATE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GPARTS_TYPE_STATE,GPartsStatePrivate))
typedef struct _GPartsStatePrivate GPartsStatePrivate;
struct _GPartsStatePrivate
{
GKeyFile *state;
};
static void
gparts_state_class_init(gpointer g_class, gpointer g_class_data);
static void
gparts_state_dispose(GObject *object);
static void
gparts_state_finalize(GObject *object);
static void
gparts_state_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void
gparts_state_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void
gparts_state_class_init(gpointer g_class, gpointer g_class_data)
{
GObjectClass *object_class = G_OBJECT_CLASS(g_class);
g_type_class_add_private(object_class, sizeof(GPartsStatePrivate));
object_class->dispose = gparts_state_dispose;
object_class->finalize = gparts_state_finalize;
object_class->get_property = gparts_state_get_property;
object_class->set_property = gparts_state_set_property;
}
static void
gparts_state_dispose(GObject *object)
{
GPartsStatePrivate *privat = GPARTS_STATE_GET_PRIVATE(object);
}
static void
gparts_state_finalize(GObject *object)
{
GPartsStatePrivate *privat = GPARTS_STATE_GET_PRIVATE(object);
if (privat->state != NULL)
{
g_key_file_free(privat->state);
}
}
static void
gparts_state_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
switch (property_id)
{
// case GPARTS_CATEGORY_MODEL_PROPID_DATABASE:
// gparts_category_model_set_database(object, value);
// break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
GType
gparts_state_get_type(void)
{
static GType type = G_TYPE_INVALID;
if (type == G_TYPE_INVALID)
{
static const GTypeInfo tinfo = {
sizeof(GPartsStateClass), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
gparts_state_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof(GPartsState), /* instance_size */
0, /* n_preallocs */
NULL, /* instance_init */
NULL /* value_table */
};
type = g_type_register_static(
G_TYPE_OBJECT,
"GPartsState",
&tinfo,
0
);
}
return type;
}
static void
gparts_state_init(GTypeInstance* instance, gpointer g_class)
{
}
static void
gparts_state_load(GPartsState *state, const gchar *filename, GError **error)
{
GKeyFile *key_file = g_key_file_new();
GPartsStatePrivate *privat = GPARTS_STATE_GET_PRIVATE(state);
gboolean success;
success = g_key_file_load_from_file(key_file, filename, G_KEY_FILE_KEEP_COMMENTS, error);
if (success)
{
if (privat->state != NULL)
{
g_key_file_free(privat->state);
}
privat->state = key_file;
}
}
static void
gparts_state_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch (property_id)
{
// case GPARTS_CATEGORY_MODEL_PROPID_DATABASE:
// gparts_category_model_set_database(object, value);
// break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}

48
src/gparts-state.h Normal file
View File

@ -0,0 +1,48 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
/*! \file gparts-state.h
*
* \brief Stores a buildable list of GObjects
*/
#define GPARTS_TYPE_STATE (gparts_state_get_type())
#define GPARTS_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GPARTS_TYPE_STATE,GPartsState))
#define GPARTS_STATE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls),GPARTS_TYPE_STATE,GPartsStateClass))
#define GPARTS_IS_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GPARTS_TYPE_STATE))
#define GPARTS_IS_STATE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls),GPARTS_TYPE_STATE))
#define GPARTS_STATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GPARTS_TYPE_STATE,GPartsStateClass))
typedef struct _GPartsState GPartsState;
typedef struct _GPartsStateClass GPartsStateClass;
struct _GPartsState
{
GObject parent;
};
struct _GPartsStateClass
{
GObjectClass parent;
};
GType
gparts_state_get_type(void);

402
src/gparts-units.c Normal file
View File

@ -0,0 +1,402 @@
/* gEDA - GPL Electronic Design Automation
* gparts - gEDA Parts Manager
* Copyright (C) 2009 Edward C. Hennessy
* Copyright (C) 2009 gEDA Contributors (see ChangeLog for details)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
*/
#include <math.h>
#include <gtk/gtk.h>
#include "gparts-database-result.h"
#include "gparts-result-model.h"
/*! \file gparts-units.c
*
* \brief Formats numeric data with units of measure.
*
* \par Supported Units
* \c AMPS Current.
*
* \c PERCENT A percentage.
*
* \c RESISTOR A resistor's value.
*
* \c VOLTS Voltage.
*/
/* FIXME Below needs to work with all compilers. The following will work in
* GCC even without C99 support, but it will issue a warning.
*/
//#ifdef __STDC__VERSION__
//#if __STDC_VERSION__ >= 199901L
#define GPARTS_SYMBOL_MICRO "\u00B5"
#define GPARTS_SYMBOL_OHM "\u2126"
//#endif
//#else
//#define GPARTS_SYMBOL_MICRO "u"
//#define GPARTS_SYMBOL_OHM ""
//#endif
typedef struct _GPartsUnitsCellDataFunc GPartsUnitsCellDataFunc;
typedef struct _GPartsUnitsFormat GPartsUnitsFormat;
typedef struct _GPartsUnitsMetricPrefix GPartsUnitsMetricPrefix;
typedef struct _GPartsUnitsPrivate GPartsUnitsPrivate;
/* \brief Holds some data
*/
struct _GPartsUnitsCellDataFunc
{
const gchar *name;
GtkTreeCellDataFunc func;
const gchar *symbol;
};
/*! \brief Junk
* \private
*
* \todo Get rid of this table by using math functions to calculate the format.
*/
struct _GPartsUnitsFormat
{
const gchar *string;
float value;
};
/*! \brief Structure for an entry in a lookup table.
* \private
*
*
*
*
*
*/
struct _GPartsUnitsMetricPrefix
{
const gchar *prefix;
const gchar *symbol;
const gchar *symbol2;
float value;
};
/*!
* \private
*
*
*
*/
struct _GPartsUnitsPrivate
{
gint column;
const char *symbol;
};
static void
gparts_units_cell_format_generic(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
static void
gparts_units_cell_format_resistor(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
static void
gparts_units_cell_format_percent(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
static const GPartsUnitsCellDataFunc*
gparts_units_find_cell_data_func(const gchar *name);
static const gchar*
gparts_units_find_format(gdouble value);
static const GPartsUnitsMetricPrefix*
gparts_units_find_metric_prefix(gdouble value);
/*
*
*
*
* The last entry in the table must have a function pointer of NULL.
*/
static const GPartsUnitsCellDataFunc gparts_units_cell_data_func[] =
{
{ "AMPS", gparts_units_cell_format_generic, "A" },
{ "PERCENT", gparts_units_cell_format_percent, NULL },
{ "RESISTOR", gparts_units_cell_format_resistor, GPARTS_SYMBOL_OHM },
{ "VOLTS", gparts_units_cell_format_generic, "V" },
{ "NONE", NULL, NULL }
};
/*
* Three significant digit table.
*
*/
static const GPartsUnitsFormat gparts_units_format[] =
{
{ "%.0f %s%s", 1000 },
{ "%.0f %s%s", 100 },
{ "%.1f %s%s", 10 },
{ "%.2f %s%s", 1 },
{ "%.0f %s%s", 0 }
};
/*!
*
*
* FIXME Add sentinel to the table.
*/
static const GPartsUnitsMetricPrefix gparts_units_metric_prefixes[] =
{
{ "yotta", "Y", "Y", 1e24 },
{ "zetta", "Z", "Z", 1e21 },
{ "exa", "E", "E", 1e18 },
{ "peta", "P", "P", 1e15 },
{ "tera", "T", "T", 1e12 },
{ "giga", "G", "G", 1e9 },
{ "mega", "M", "M", 1e6 },
{ "kilo", "k", "k", 1e3 },
{ "", "", "", 1 },
{ "milli", "m", "m", 1e-3 },
{ "micro", GPARTS_SYMBOL_MICRO, "u", 1e-6 },
{ "nano", "n", "n", 1e-9 },
{ "pico", "p", "p", 1e-12 },
{ "femto", "f", "f", 1e-15 },
{ "atto", "a", "a", 1e-18 },
{ "zepto", "z", "z", 1e-21 },
{ "yocto", "y", "y", 1e-24 },
{ "", "", "", 0 }
};
/*! \brief Sets the numeric format and units for a GtkTreeViewColumn's cells.
* \public
*
* \param [in] column The tree view column to recieve the format.
* \param [in] renderer The cell renerer within the tree view column.
* \param [in] index The tree model's zero based column index of the data.
* \param [in] units The name of the numeric format and units to use.
*/
void
gparts_units_attach_cell_data_func(GtkTreeViewColumn *column, GtkCellRenderer *renderer, gint index, const gchar *units)
{
GPartsUnitsCellDataFunc *func = gparts_units_find_cell_data_func(units);
GPartsUnitsPrivate *private = g_new0(GPartsUnitsPrivate,1);
private->column = index;
private->symbol = func->symbol;
gtk_tree_view_column_set_cell_data_func(
column,
renderer,
func->func,
private,
g_free
);
}
/*! \brief Format a cell with a metric value.
*
*
*
* \param [in] column The GtkTreeViewColumn.
* \param [in] cell The GtkCellRendererText.
* \param [in] model A GtkTreeModel where the original data resides.
* \param [in] iter A GtkTreeIter for the row being formatted.
* \param [in] data The resitor value's zero based column index, cast into a pointer.
*/
static void
gparts_units_cell_format_generic(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
GValue value = {0};
gtk_tree_model_get_value(
model,
iter,
((GPartsUnitsPrivate*) data)->column,
&value
);
if (G_IS_VALUE(&value) && G_VALUE_HOLDS_DOUBLE(&value))
{
double n = g_value_get_double(&value);
GString *string = g_string_new("");
const GPartsUnitsMetricPrefix* prefix = gparts_units_find_metric_prefix(n);
const gchar *format = gparts_units_find_format(n/prefix->value);
g_string_printf(string, format, n/prefix->value, prefix->symbol, ((GPartsUnitsPrivate*) data)->symbol);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_take_string(&value, string->str);
g_string_free(string, FALSE);
g_object_set_property(G_OBJECT(cell), "text", &value);
g_value_unset(&value);
}
}
/*! \brief Format a cell as a resistor's value.
*
* \param [in] column The GtkTreeViewColumn.
* \param [in] cell The GtkCellRendererText.
* \param [in] model A GtkTreeModel where the original data resides.
* \param [in] iter A GtkTreeIter for the row being formatted.
* \param [in] data The resitor value's zero based column index, cast into a pointer.
*
* TODO Use the resistor's tolerance (the next column) to determine the number
* of digits to show.
*/
static void
gparts_units_cell_format_resistor(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
GValue value = {0};
gtk_tree_model_get_value(
model,
iter,
((GPartsUnitsPrivate*) data)->column,
&value
);
if (G_IS_VALUE(&value) && G_VALUE_HOLDS_DOUBLE(&value))
{
double n = g_value_get_double(&value);
GString *string = g_string_new("");
const GPartsUnitsMetricPrefix* prefix = gparts_units_find_metric_prefix(n);
const gchar *format = gparts_units_find_format(n/prefix->value);
g_string_printf(string, format, n/prefix->value, prefix->symbol, GPARTS_SYMBOL_OHM);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_take_string(&value, string->str);
g_string_free(string, FALSE);
g_object_set_property(G_OBJECT(cell), "text", &value);
g_value_unset(&value);
}
}
/*! \brief Format a cell as a percentage.
*
* \param [in] column The GtkTreeViewColumn.
* \param [in] cell The GtkCellRendererText.
* \param [in] model A GtkTreeModel where the original data resides.
* \param [in] iter A GtkTreeIter for the row being formatted.
* \param [in] data The model's zero based column index, cast into a pointer.
*
* FIXME With a fractional percent, this function will only display the most
* significant digit. So, "0.15%" becomes "0.1%." This function should make
* an attempt to display all digits, without displaying additional trailing
* zeros.
*/
static void
gparts_units_cell_format_percent(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
GValue value = {0};
gtk_tree_model_get_value(
model,
iter,
((GPartsUnitsPrivate*) data)->column,
&value
);
if (G_IS_VALUE(&value) && G_VALUE_HOLDS_DOUBLE(&value))
{
gint digits = 0;
gdouble percent = g_value_get_double(&value) * 100;
GString *string = g_string_new("");
if (percent != 0)
{
digits = ceil(-log10(fabs(percent)));
if (digits < 0)
{
digits = 0;
}
}
g_string_printf(string, "%.*f %%", digits, percent);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_take_string(&value, string->str);
g_string_free(string, FALSE);
g_object_set_property(G_OBJECT(cell), "text", &value);
g_value_unset(&value);
}
}
/*! \brief Finds the format data using the format name.
*
* \param [in] name
* \return A pointer to a GPartsUnitsCellDataFunc. This function does not
* return NULL.
*/
static const GPartsUnitsCellDataFunc*
gparts_units_find_cell_data_func(const gchar *name)
{
GPartsUnitsCellDataFunc *func = &gparts_units_cell_data_func[0];
while (func->func != NULL && g_strcmp0(name, func->name) != 0)
{
func++;
}
return func;
}
/* TODO Get rid of this function by using math functions to calculate the format.
*/
static const gchar*
gparts_units_find_format(gdouble value)
{
const GPartsUnitsFormat *format = &gparts_units_format[0];
while (fabs(value) < format->value)
{
format++;
}
return format->string;
}
/*! \brief Finds the right metric prefix for a given value.
*
* \param [in] value The value in prefix-less units.
* \return A pointer to a GPartsUnitsMetricPrefix. This function does not
* return NULL.
*/
static const GPartsUnitsMetricPrefix*
gparts_units_find_metric_prefix(gdouble value)
{
const GPartsUnitsMetricPrefix *prefix = &gparts_units_metric_prefixes[0];
while (fabs(value) < prefix->value)
{
prefix++;
}
return prefix;
}

9
src/gparts-units.h Normal file
View File

@ -0,0 +1,9 @@
/*! \file gparts-units.h
*
* \brief Formatting for GtkTreeViewColumn's cells.
*
* This module provides formatting for cells within a GtkTreeViewColumn.
*/
void
gparts_units_attach_cell_data_func(GtkTreeViewColumn *column, GtkCellRenderer *renderer, gint index, const gchar *units);

687
src/gparts.xml Normal file
View File

@ -0,0 +1,687 @@
<interface>
<object class="GtkUIManager" id="uimanager">
<child>
<object class="GtkActionGroup" id="main_action_group">
<child>
<object class="GtkAction" id="database">
<property name="name">database</property>
<property name="label">_Database</property>
</object>
</child>
<child>
<object class="GtkAction" id="database-connect">
<property name="name">database-connect</property>
<property name="label">Connect</property>
<property name="stock-id">gtk-connect</property>
</object>
</child>
<child>
<object class="GtkAction" id="database-disconnect">
<property name="name">database-disconnect</property>
<property name="label">Disconnect</property>
<property name="stock-id">gtk-disconnect</property>
</object>
</child>
<child>
<object class="GtkAction" id="view">
<property name="name">view</property>
<property name="label">_View</property>
</object>
</child>
<child>
<object class="GtkAction" id="view-customize">
<property name="name">view-customize</property>
<property name="label">Customize...</property>
</object>
</child>
<child>
<object class="GtkAction" id="view-refresh">
<property name="name">refresh</property>
<property name="label">_Refresh</property>
<property name="stock-id">gtk-refresh</property>
</object>
</child>
<child>
<object class="GtkAction" id="view-edit">
<property name="name">view-edit</property>
<property name="label">Edit</property>
</object>
</child>
<child>
<object class="GtkAction" id="test-popup-2">
<property name="name">popup-2</property>
<property name="label">Test Popup 2</property>
</object>
</child>
</object>
</child>
<ui>
<menubar name="main_menu">
<menu action="database">
<menuitem action="database-connect"/>
<menuitem action="database-disconnect"/>
</menu>
<menu action="view">
<menuitem action="view-refresh"/>
<menuitem action="view-edit"/>
<menuitem action="view-customize"/>
</menu>
</menubar>
<toolbar name="main_toolbar">
<toolitem action="database-connect"/>
<toolitem action="view-refresh"/>
</toolbar>
</ui>
</object>
<object class="GtkWindow" id="main">
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">TRUE</property>
<child>
<object class="GtkMenuBar" constructor="uimanager" id="main_menu">
<property name="visible">TRUE</property>
</object>
<packing>
<property name="expand">FALSE</property>
<property name="fill">FALSE</property>
</packing>
</child>
<child>
<object class="GtkToolbar" constructor="uimanager" id="main_toolbar">
<property name="visible">TRUE</property>
</object>
<packing>
<property name="expand">FALSE</property>
<property name="fill">FALSE</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">TRUE</property>
<!-- A window for browsing all the companies in the library -->
<child>
<object class="GtkScrolledWindow" id="companies-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="companies-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="companies-tab">
<property name="label">Companies</property>
</object>
</child>
<!-- A window for browsing all the devices in the library -->
<child>
<object class="GtkScrolledWindow" id="devices-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="devices-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="devices-tab">
<property name="label">Devices</property>
</object>
</child>
<!-- A window for browsing all the documentation in the library -->
<child>
<object class="GtkScrolledWindow" id="documentation-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="documentation-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="documentation-tab">
<property name="label">Documentation</property>
</object>
</child>
<!-- A window for browsing all the footprints in the library -->
<child>
<object class="GtkHPaned" id="footprints-hpaned">
<property name="visible">TRUE</property>
<child>
<object class="GtkScrolledWindow" id="footprints-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="footprints-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
<child>
<object class="gparts-preview" id="footprints-graphic-view">
<property name="height-request">200</property>
<property name="visible">TRUE</property>
<property name="width-request">200</property>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="footprints-tab">
<property name="label">Footprints</property>
</object>
</child>
<!-- A window for browsing all the packages in the library -->
<child>
<object class="GtkHPaned" id="symbols-hpaned">
<property name="visible">TRUE</property>
<child>
<object class="GtkScrolledWindow" id="packages-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="packages-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="packages-footprints-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="packages-footprints-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">140</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="packages-tab">
<property name="label">Packages</property>
</object>
</child>
<!-- A window for browsing all the parts in the library -->
<child>
<object class="GtkHPaned" id="zippy">
<property name="visible">TRUE</property>
<child>
<object class="GtkScrolledWindow" id="category-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="category-view">
<property name="visible">TRUE</property>
<property name="width-request">200</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkHPaned" id="hpaned-2">
<property name="visible">TRUE</property>
<child>
<object class="GtkScrolledWindow" id="parts-scrolled-window">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GPartsResultView" id="parts-tree-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">600</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkVPaned" id="vpaned-1">
<property name="visible">TRUE</property>
<child>
<object class="GtkScrolledWindow" id="symbols-scrolled-window">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="gparts-preview" id="symbols-graphic-view">
<property name="height-request">200</property>
<property name="visible">TRUE</property>
<property name="width-request">200</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="symbols-scrolled-window">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="symbols-tree-view">
<property name="height-request">200</property>
<property name="visible">TRUE</property>
<property name="width-request">200</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="parts-tab">
<property name="label">Parts</property>
</object>
</child>
<!-- A window for browsing all the symbols in the library -->
<child>
<object class="GtkVPaned" id="symbols-window-vpaned-1">
<property name="visible">TRUE</property>
<child>
<object class="GtkHPaned" id="symbols-window-hpaned-1">
<property name="visible">TRUE</property>
<child>
<object class="GtkScrolledWindow" id="symbols-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="symbols-view">
<property name="height-request">480</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
<child>
<object class="gparts-preview" id="symbols-graphic-view">
<property name="height-request">200</property>
<property name="visible">TRUE</property>
<property name="width-request">200</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="symbol-details-scrolled">
<property name="visible">TRUE</property>
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<child>
<object class="GtkTreeView" id="symbol-details-view">
<property name="height-request">100</property>
<property name="visible">TRUE</property>
<property name="width-request">640</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="symbols-tab">
<property name="label">Symbols</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<!-- A window for browsing all the companies in the library -->
<object class="GtkWindow" id="companies-window">
<property name="title">Companies</property>
</object>
<!-- A window for browsing all the devices in the library -->
<object class="GtkWindow" id="devices-window">
<property name="title">Devices</property>
</object>
<!-- A window for browsing all the documentation in the library -->
<object class="GtkWindow" id="documentation-window">
<property name="title">Documentation</property>
</object>
<!-- A window for browsing all the footprints in the library -->
<object class="GtkWindow" id="footprints-window">
<property name="title">Footprints</property>
</object>
<!-- A window for browsing all the packages in the library -->
<object class="GtkWindow" id="packages-window">
<property name="title">Packages</property>
</object>
<!-- A window for browsing all the symbols in the library -->
<object class="GtkWindow" id="symbols-window">
<property name="title">Symbols</property>
</object>
<object class="GtkDialog" id="preferences">
<child internal-child="vbox">
<object class="GtkVBox" id="vbox111">
<property name="visible">TRUE</property>
<child>
<object class="GtkNotebook" id="colorthing">
<property name="visible">TRUE</property>
<child>
<object class="GtkVBox" id="vbox111">
<property name="visible">TRUE</property>
<child>
<object class="GtkTreeView" id="colortree">
<property name="visible">TRUE</property>
</object>
</child>
<child>
<object class="GtkHButtonBox" id="hbox11">
<property name="layout-style">GTK_BUTTONBOX_START</property>
<property name="visible">TRUE</property>
<child>
<object class="GtkButton" id="button_add">
<property name="label">gtk-add</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_remove">
<property name="label">gtk-remove</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
</object>
<packing>
<property name="expand">FALSE</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="hbox111">
<property name="visible">TRUE</property>
<child>
<object class="GtkButton" id="button_help">
<property name="label">gtk-help</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_cancel">
<property name="label">gtk-cancel</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_ok">
<property name="label">gtk-apply</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
</object>
</child>
<action-widgets>
<action-widget response="3">button_ok</action-widget>
<action-widget response="-5">button_cancel</action-widget>
</action-widgets>
</object>
<object class="GtkDialog" id="database-login-mysql">
<property name="title">Connect to Database</property>
<child internal-child="vbox">
<object class="GtkVBox" id="vbox">
<property name="visible">TRUE</property>
<child>
<object class="GtkTable" id="vbox">
<property name="border_width">10</property>
<property name="column_spacing">5</property>
<property name="n_columns">1</property>
<property name="n_rows">5</property>
<property name="row_spacing">5</property>
<property name="visible">TRUE</property>
<child>
<object class="GtkLabel" id="user-name-label">
<property name="label">User Name</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="user-name-entry">
<property name="text">root</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="password-label">
<property name="label">Password</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password-entry">
<property name="visible">TRUE</property>
<property name="visibility">FALSE</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="server-label">
<property name="label">Server</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="server-entry">
<property name="text">localhost</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="database-label">
<property name="label">Database</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="database-entry">
<property name="text">GParts</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="filename-label">
<property name="label">Filename</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="filename-entry">
<property name="text">gparts</property>
<property name="visible">TRUE</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">4</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="buttons">
<property name="visible">TRUE</property>
<child>
<object class="GtkButton" id="button-help">
<property name="label">gtk-help</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
<child>
<object class="GtkButton" id="button-cancel">
<property name="label">gtk-cancel</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
<child>
<object class="GtkButton" id="button-ok">
<property name="label">gtk-ok</property>
<property name="use-stock">TRUE</property>
<property name="visible">TRUE</property>
</object>
</child>
</object>
</child>
<action-widgets>
<action-widget response="3">button-ok</action-widget>
<action-widget response="-5">button-cancel</action-widget>
</action-widgets>
</object>
<object class="GPartsObjectList" id="controllers">
</object>
</interface>

26
src/temp.txt Normal file
View File

@ -0,0 +1,26 @@
** (gparts:29057): DEBUG: Supported 1
** (gparts:29057): DEBUG: Path test/libgparts-mysql
** (gparts:29057): DEBUG: (nil)
** (gparts:29057): DEBUG: ./.libs/: cannot read file data: Is a directory
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s WHERE DeviceID = $(DeviceID)
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s
** (gparts:29057): DEBUG: Template: SELECT * FROM %s WHERE SymbolID = $(SymbolID)
** (gparts:29064): DEBUG: Supported 1
** (gparts:29064): DEBUG: Path test/libgparts-mysql
** (gparts:29064): DEBUG: (nil)
** (gparts:29064): DEBUG: ./.libs/: cannot read file data: Is a directory
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s WHERE DeviceID = $(DeviceID)
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s
** (gparts:29064): DEBUG: Template: SELECT * FROM %s WHERE SymbolID = $(SymbolID)

BIN
test_data/CD0603_1005-Z.pdf Normal file

Binary file not shown.

15933
tmp/parts-bourns.sql Normal file

File diff suppressed because it is too large Load Diff

1540
tmp/parts-vishay-sprague.sql Normal file

File diff suppressed because it is too large Load Diff

10736
tmp/symbols.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
#!/usr/bin/python
##############################################################################
##
## Extracts data from the existing symbol library for GPart's database.
##
## The command line parameter (required) specifies the top level gEDA
## directory.
##
##############################################################################
import os
import re
import sys
import csv
company = "ON Semiconductor"
csv_file = "../tmp/onsemi-switching-diodes.csv"
print "CALL AddCompany("
print " '%s'" % company
print " );"
print
def process(input):
for line in input:
print "CALL AddDiode("
print " '%s'," % company
print " '%s'," % line[0]
print " '%s'," % line[9].partition(' ')[0]
print " '%s'," % 'DIODE'
print " %s," % line[4]
print " %s," % line[5]
print " %s" % 'NULL'
print " );"
print
if __name__ == "__main__":
input = csv.reader(open(csv_file, "r"))
process(input)

98
tools/symbols.py Executable file
View File

@ -0,0 +1,98 @@
#!/usr/bin/python
##############################################################################
##
## Extracts data from the existing symbol library for GPart's database.
##
## The command line parameter (required) specifies the top level gEDA
## directory.
##
##############################################################################
import os
import re
import sys
top = sys.argv[1]
pattern = re.compile( "^(.+?)=(.*)$", re.M )
## Parse symbol directories and return a list of the symbol files. The symbol
## files include path relative to the top level gEDA directory.
##
## TODO Filter out non-symbol files.
##
def get_symbols():
dirs = [ 'sym' ]
symbols = list()
for dir in dirs:
files = os.listdir( os.path.join( top, dir ) )
for file in files:
path = os.path.join( dir, file )
if os.path.isdir( os.path.join( top, path ) ):
dirs.append( path )
else:
symbols.append( path )
return symbols
## Output SQL commands to add details (comments) to the database.
##
## TODO Add code to escape any double quotes in the comment string.
##
def output_details( devices ):
for ( symbol, attributes ) in devices.iteritems():
if 'comment' in attributes:
for comment in attributes['comment']:
print "CALL AddSymbolDetail("
print " '%s'," % symbol
print " \"%s\"" % comment
print " );"
print
## Output SQL commands to add devices to the database.
##
def output_devices( devices ):
output = dict()
for device in devices.itervalues():
for name in device.get( 'device', list() ):
if name not in output:
print "CALL AddDevice("
print " '%s'" % name
print " );"
print
output[name] = 1
## Output SQL commands to add symbols to the database.
##
def output_symbols( devices ):
for ( symbol, attributes ) in devices.iteritems():
if 'device' in attributes:
print "CALL AddSymbol("
print " '%s'," % attributes['device'][0]
print " '%s'" % symbol
print " );"
print
## Parses symbol files for attributes. Returns a dictionary mapping symbol
## filenames to another dictionary. The next dictionary maps attribute names
## to a list of attribute values.
##
def parse_symbols( symbols ):
devices = dict()
for symbol in symbols:
attributes = devices.setdefault( symbol, dict() )
file = os.path.join( top, symbol )
data = open( file, 'r' ).read()
for match in pattern.finditer( data ):
name = match.group( 1 )
value = match.group( 2 )
attributes.setdefault( name, list() ).append( value )
return devices
if __name__ == "__main__":
symbols = get_symbols()
devices = parse_symbols( symbols )
output_devices( devices )
output_symbols( devices )
output_details( devices )