diff options
| author | fisharebest <fisharebest@gmail.com> | 2011-08-04 19:03:17 +0000 |
|---|---|---|
| committer | fisharebest <fisharebest@gmail.com> | 2011-08-04 19:03:17 +0000 |
| commit | 3a66749533ae4ec372c95f7b0a6363efa4f5d294 (patch) | |
| tree | 48931d265ee51c08f56820a767237975b00ebc3a /modules_v3/tree | |
| parent | d83d060a1ac10dc72134c3d4804e89b04cc68ad6 (diff) | |
| download | webtrees-3a66749533ae4ec372c95f7b0a6363efa4f5d294.tar.gz webtrees-3a66749533ae4ec372c95f7b0a6363efa4f5d294.tar.bz2 webtrees-3a66749533ae4ec372c95f7b0a6363efa4f5d294.zip | |
#821050 - Error calling page after update to 1.2.2
Diffstat (limited to 'modules_v3/tree')
82 files changed, 1910 insertions, 0 deletions
diff --git a/modules_v3/tree/class_treeview.php b/modules_v3/tree/class_treeview.php new file mode 100644 index 0000000000..7a43196194 --- /dev/null +++ b/modules_v3/tree/class_treeview.php @@ -0,0 +1,458 @@ +<?php +// Class file for the tree navigator +// +// Note : NEVER use person or family id as ids because a same person could +// appear more than once in the tree. +// +// webtrees: Web based Family History software +// Copyright (C) 2011 webtrees development team. +// +// 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-1307 USA +// +// $Id$ + +if (!defined('WT_WEBTREES')) { + header('HTTP/1.0 403 Forbidden'); + exit; +} + +require_once 'includes/functions/functions_charts.php'; + +class TreeView { + var $name; + var $allPartners; + + /** + * Treeview Constructor + * @param string $name the name of the TreeView object's instance + */ + function __construct($name='tree') { + $this->name = $name; + + // Read if all partners must be shown or not + $allPartners = safe_GET('allPartners'); + // if allPartners not specified in url, we try to read the cookie + if ($allPartners == '') { + if (isset($_COOKIE['allPartners'])) + $allPartners = $_COOKIE['allPartners']; + else + $allPartners = 'true'; // That is now the default value + } + $allPartners = ($allPartners == 'true' ? true : false); + $this->allPartners = $allPartners; + } + + /** + * Draw the viewport which creates the draggable/zoomable framework + * Size is set by the container, as the viewport can scale itself automatically + * @param string $rootPersonId the id of the root person + * @param int $generations number of generations to draw + */ + public function drawViewport($rootPersonId, $generations, $style) { + global $GEDCOM, $WT_IMAGES; + + $rootPersonId = check_rootid($rootPersonId); + $rootPerson = WT_Person::getInstance($rootPersonId); + if (is_null($rootPerson)) + $rootPerson = new WT_Person(''); + + if (WT_SCRIPT_NAME == 'individual.php') + $path = 'individual.php?pid='.$rootPerson->getXref().'&ged='.$GEDCOM.'&allPartners='.($this->allPartners ? "false" : "true").'#tree'; + else + $path = 'module.php?mod=tree&mod_action=treeview&rootid='.$rootPerson->getXref().'&allPartners='.($this->allPartners ? "false" : "true"); + $r = '<a name="tv_content"></a><div id="'.$this->name.'_out" dir="ltr" class="tv_out">'; + + // Read styles (20 maxi) in a hidden list + $sd = WT_MODULES_DIR.'tree/css/styles/'; + $rs = '<ul id="tvStylesSubmenu">'; + $cs = '<img src="'.$sd.'default/button.gif" alt="d" onclick="'.$this->name.'Handler.style(\''.$sd.'\', \'default\', this);" title="'.WT_I18N::translate('Style').'" />'; + $rs .= '<li class="tv_button'.($style == '' || $style=='default' ? ' tvPressed' : '').'">'.$cs.'</li>'; + $nbStyles = 1; + if (@is_dir($sd) && @is_readable($sd) && ($d=@opendir($sd))) { + while (($s = readdir($d)) !== false && ($nbStyles < 20)) { + if ($s[0] == '.' || $s=='default' || !is_dir($sd.$s)) + continue; + $sHTML = '<img src="'.$sd.$s.'/button.gif" alt="'.$s[0].'" onclick="'.$this->name.'Handler.style(\''.$sd.'\', \''.$s.'\', this);" title="'.WT_I18N::translate('Style').'" />'; + if ($s == $style) { + $cs = $sHTML; + $pressedState = ' tvPressed'; + } + else + $pressedState =''; + $rs .= '<li class="tv_button'.$pressedState.'">'.$sHTML.'</li>'; + $nbStyles++; + } + } + $rs .= '</ul>'; + + // Add the toolbar + $r.= + '<div id="tv_tools"><ul>'. + // TODO: can we change the toolbar's orientation automatically, when it is dragged to a vertical/horizontal edge? + '<li id="tvToolsHandler" title="'.WT_I18N::translate('Move the toolbar').'"></li>'. + '<li id="tvbZoomIn" class="tv_button"><img src="'.$WT_IMAGES['zoomin'].'" alt="'.WT_I18N::translate('Zoom in').'" title="'.WT_I18N::translate('Zoom in').'" /></li>'. + '<li id="tvbZoomOut" class="tv_button"><img src="'.$WT_IMAGES['zoomout'].'" alt="'.WT_I18N::translate('Zoom out').'" title="'.WT_I18N::translate('Zoom out').'" /></li>'. + '<li id="tvbNoZoom" class="tv_button"><img src="'.WT_MODULES_DIR.'tree/images/zoom0.png" alt="'.WT_I18N::translate('Reset').'" title="'.WT_I18N::translate('Reset').'" /></li>'. + '<li id="tvbLeft" class="tv_button"><img src="'.$WT_IMAGES['ldarrow'].'" alt="'.WT_I18N::translate('Align left').'" title="'.WT_I18N::translate('Align left').'" /></li>'. + '<li id="tvbCenter" class="tv_button"><img src="'.$WT_IMAGES['center'].'" alt="'./* I18N: verb/action */ WT_I18N::translate('Center').'" title="'.WT_I18N::translate('Center').'" /></li>'. + '<li id="tvbRight" class="tv_button"><img src="'.$WT_IMAGES['rdarrow'].'" alt="'.WT_I18N::translate('Align right').'" title="'.WT_I18N::translate('Align right').'" /></li>'. + '<li id="tvbDates" class="tv_button tvPressed"><img src="'.WT_MODULES_DIR.'tree/images/dates.png" alt="'.WT_I18N::translate('Show year of birth and death').'" title="'.WT_I18N::translate('Show year of birth and death').'" /></li>'. + '<li id="tvbCompact" class="tv_button"><img src="'.WT_MODULES_DIR.'tree/images/compact.png" alt="'.WT_I18N::translate('Use compact layout').'" title="'.WT_I18N::translate('Use compact layout').'" /></li>'. + // TODO: this is temporarily disabled (as it sends a flood of AJAX requests?) + //'<li id="tvbOpen" class="tv_button"><img src="'.$WT_IMAGES["media"].'" alt="o" title="'.WT_I18N::translate('Show all details').'" /></li>'. + //'<li id="tvbClose" class="tv_button"><img src="'.$WT_IMAGES["fambook"].'" alt="f" title="'.WT_I18N::translate('Hide all details').'" /></li>'. + // If the position/order of the style button moves, update TreeViewHandler() in treeview.js + '<li id="tvStyleButton" class="tv_button">'.$cs.'</li>'. + '<li id="tvbPrint" class="tv_button"><img src="'.WT_MODULES_DIR.'tree/images/print.png" alt="p" title="'./* I18N: verb/action */ WT_I18N::translate('Print').'" /></li>'. + '<li class="tv_button'.($this->allPartners ? ' tvPressed' : '').'"><a href="'.$path.'"><img src="'.$WT_IMAGES["sfamily"].'" alt="'.WT_I18N::translate('Show all spouses and ancestors').'" title="'.WT_I18N::translate('Show all spouses and ancestors').'" /></a></li>'; + if (safe_GET('mod_action') != 'treeview') { + $r.='<li class="tv_button"><a href="module.php?mod=tree&mod_action=treeview&rootid='.$rootPerson->getXref().'#tv_content" title="'. /* I18N: Button label - view this chart in full-screen mode */ WT_I18N::translate('Full screen').'"><img src="'.$WT_IMAGES["fscreen"].'" alt="full screen" /></a></li>'; + } + // Help, and hidden loading image + $r.='<li class="tv_button">'.help_link("TV_MODULE", 'tree').'</li> + <li class="tv_button" id="'.$this->name.'_loading"><img src="images/loading.gif" alt="Loading..." /></li> +</ul>'.$rs; + $r.='</div><div id="'.$this->name.'_in" class="tv_in">'; + $parent = null; + $r.=$this->drawPerson($rootPerson, $generations, 0, $parent, '', true); + $r.='</div></div>'; // Close the tv_in and the tv_out div + $r.='<script type="text/javascript">var '.$this->name.'Handler = new TreeViewHandler("'.$this->name.'", '.($this->allPartners ? 'true' : 'false').', '.$nbStyles.');</script>'; + return $r; + } + + /** + * Return a JSON structure to a JSON request + * @param string $list list of JSON requests + */ + public function getPersons($list) { + $list = explode(';', $list); + $r = array(); + foreach($list as $jsonRequest) { + $firstLetter = substr($jsonRequest, 0, 1); + $jsonRequest = substr($jsonRequest, 1); + switch($firstLetter) { + case 'c': + $fidlist = explode(',', $jsonRequest); + $flist = array(); + foreach($fidlist as $fid) + $flist[] = WT_Family::getInstance($fid); + $r[] = $this->drawChildren($flist, 1, true); + break; + case 'p': + $params = explode('@', $jsonRequest); + $fid = $params[0]; + $order = $params[1]; + $f = WT_Family::getInstance($fid); + $p = $f->getHusband(); + $r[] = $this->drawPerson($f->getHusband(), 0, 1, $f, $order); + break; + } + } + return json_encode($r); + } + + /** + * Get the details for a person and their life partner(s) + * @param string $pid the person id to return the details for + */ + public function getDetails($pid) { + + $person = WT_Person::getInstance($pid); + + $r = $this->getPersonDetails($person, $person, null); + foreach ($person->getSpouseFamilies() as $family) { + if (!empty($family)) { + $partner = $family->getSpouse($person); + if (!empty($partner)) + $r .= $this->getPersonDetails($person, $partner, $family); + } + } + return $r; + } + + /** + * Get full resolution medias + * @param string $medias the list of medias to return + */ + public function getMedias($medias) { + $medias = explode(';', $medias); + $nb = count($medias); + $r = array(); + for ($i=0; $i<$nb; $i++) { + $mid = $medias[$i]; + $m = WT_Media::getInstance($mid); + $r[] = $m->getServerFilename(); + } + return json_encode($r); + } + + + /** + * Return the details for a person + * @param Person $person the person to return the details for + */ + private function getPersonDetails($personGroup, $person, $family) { + global $WT_IMAGES; + + $r = '<div class="tv'.$person->getSex().' tv_person_expanded">'; + $r .= $this->getThumbnail($personGroup, $person); + $r .= '<a class="tv_link" href="'.$person->getHtmlUrl().'">'.$person->getFullName().'</a> <a href="module.php?mod=tree&mod_action=treeview&allPartners='.($this->allPartners ? 'true' : 'false').'&rootid='.$person->getXref().'" title="'.WT_I18N::translate('Interactive tree of %s', htmlspecialchars(strip_tags($person->getFullName()))).'"><img src="'.$WT_IMAGES['tree'].'" class="tv_link tv_treelink" /></a>'; + $r .= '<br /><b>'.WT_Gedcom_Tag::getAbbreviation('BIRT').'</b> '.$person->getBirthDate()->Display().' '.$person->getBirthPlace(); + if ($family) { + $r .= '<br /><b>'.WT_Gedcom_Tag::getAbbreviation('MARR').'</b> '.$family->getMarriageDate()->Display().' <a href="'.$family->getHtmlUrl().'"><img src="'.$WT_IMAGES['button_family'].'" class="tv_link tv_treelink" title="'.htmlspecialchars(strip_tags($family->getFullName())).'" /></a>'.$family->getMarriagePlace(); + } + if ($person->isDead()) + $r .= '<br /><b>'.WT_Gedcom_Tag::getAbbreviation('DEAT').'</b> '.$person->getDeathDate()->Display().' '.$person->getDeathPlace(); + $r.= '</div>'; + return $r; + } + + /** + * Draw the children for some families + * @param Array $familyList array of families to draw the children for + * @param int $gen number of generations to draw + * @param boolean $ajax setted to true for an ajax call + */ + private function drawChildren($familyList, $gen=1, $ajax=false) { + $r =''; + $flWithChildren = array(); + $f2load = array(); + $tc = 0; + foreach($familyList as $f) { + if (empty($f)) + continue; + $nbcf = $f->getNumberOfChildren(); + if ($nbcf > 0) { + $flWithChildren[] = $f; + $f2load[] = $f->getXref(); + $tc += $nbcf; + } + } + if ($tc) { + $f2load = implode(',', $f2load); + if (!$ajax) + $r .= '<td align="right"'.($gen == 0 ? ' abbr="c'.$f2load.'"' : '').'>'; + $nbc = 0; + foreach($flWithChildren as $f) { + foreach ($f->getChildren() as $child) { + $nbc++; + if ($tc == 1) + $co = 'c'; // unique + elseif ($nbc == 1) + $co = 't'; // first + elseif($nbc == $tc) + $co = 'b'; //last + else + $co = 'h'; + $fam = null; + $r .= $this->drawPerson($child, $gen-1, -1, $fam, $co); + } + } + if (!$ajax) + $r .= '</td>'.$this->drawHorizontalLine(); + } + return $r; + } + + /** + * Draw a person in the tree + * @param Person $person The Person object to draw the box for + * @param int $gen The number of generations up or down to print + * @param int $state Whether we are going up or down the tree, -1 for descendents +1 for ancestors + * @param Family $pfamily + * @param string $order first (1), last(2), unique(0), or empty. Required for drawing lines between boxes + * + * Notes : "spouse" means explicitely married partners. Thus, the word "partner" + * (for "life partner") here fits much better than "spouse" or "mate" + * to translate properly the modern french meaning of "conjoint" + */ + private function drawPerson($person, $gen, $state=0, $pfamily, $order, $isRoot=false) { + global $TEXT_DIRECTION; + + if ($gen < 0 || empty($person)) + return; + + if (!empty($pfamily)) + $partner = $pfamily->getSpouse($person); + else { + $partner = $person->getCurrentSpouse(); + $fams = $person->getSpouseFamilies(); + $pfamily = end($fams); + } + + if ($isRoot) + $r = '<table id="tvTreeBorder" class="tv_tree"><tbody><tr><td id="tv_tree_topleft"></td><td id="tv_tree_top"><div>'. + WT_I18N::translate('Interactive tree of %s',$person->getFullName()). + '</div></td><td id="tv_tree_topright"></td></tr><tr><td id="tv_tree_left"></td><td>'; + else $r = ''; + /* height 1% : this hack enable the div auto-dimensionning in td for FF & Chrome */ + $r .= '<table class="tv_tree"'.($isRoot ? ' id="tv_tree"' : '').' style="height: 1%"><tbody><tr>'; + + if ($state<=0) { + // draw children + $r.=$this->drawChildren($person->getSpouseFamilies(), $gen); + } else { + // draw the parent's lines + $r .= $this->drawVerticalLine($order).$this->drawHorizontalLine(); + } + + /* draw the person. Do NOT add person or family id as an id, since a same person could appear more than once in the tree !!! */ + // Fixing the width for td to the box initial width when the person is the root person fix a rare bug that happen when a person without child and without known parents is the root person : an unwanted white rectangle appear at the right of the person's boxes, otherwise. + $r .= '<td'.($isRoot ? ' style="width:1px"' : '').'><div class="tv_box'.($isRoot ? ' rootPerson' : '').'" dir="'.$TEXT_DIRECTION.'" style="text-align: '.($TEXT_DIRECTION=="rtl" ? "right":"left").'; direction: '.$TEXT_DIRECTION.'" abbr="'.$person->getXref().'" onclick="'.$this->name.'Handler.expandBox(this, event);">'; + $r .= $this->drawPersonName($person); + $fop = Array(); // $fop is fathers of partners + if (!is_null($partner)) { + $sfams = $person->getSpouseFamilies(); + foreach ($sfams as $famid=>$family) { + $p = $family->getSpouse($person); + if (!empty($p)) { + if (($p->equals($partner)) || $this->allPartners) { + $pf = $p->getPrimaryChildFamily(); + if (!empty($pf)) + $fop[] = Array($pf->getHusband(), $pf); + $r .= $this->drawPersonName($p); + if (!$this->allPartners) + break; // we can stop here the foreach loop + } + } + } + } + $r .= '</div></td>'; + + $fatherFamily = $person->getPrimaryChildFamily(); + if (!empty($fatherFamily)) + $father = $fatherFamily->getHusband(); + if (!empty($father) || count($fop) || ($state < 0)) + $r .= $this->drawHorizontalLine(); + + /* draw the parents */ + if ($state >= 0 && (!empty($father) || count($fop))) { + $unique = (empty($father) || count($fop) == 0); + $r .= '<td align="left"><table class="tv_tree"><tbody>'; + if (!empty($father)) { + $u = ($unique ? 'c' : 't'); + $r .= '<tr><td '.($gen == 0 ? ' abbr="p'.$fatherFamily->getXref().'@'.$u.'"' : '').'>'; + $r .= $this->drawPerson($father, $gen-1, 1, $fatherFamily, $u); + $r .= '</td></tr>'; + } + if (count($fop)) { + $n = 0; + $nb = count($fop); + foreach($fop as $p) { + $n++; + $u = ($unique ? 'c' : ($n == $nb || empty($p[1]) || !$this->allPartners ? 'b' : 'h')); + $r .= '<tr><td '.($gen == 0 ? ' abbr="p'.$p[1]->getXref().'@'.$u.'"' : '').'>'.$this->drawPerson($p[0], $gen-1, 1, $p[1], $u).'</td></tr>'; + } + } + $r .= '</tbody></table></td>'; + } + if ($state < 0) { + $r .= $this->drawVerticalLine($order); + } + $r .= '</tr></tbody></table>'; + if ($isRoot) + $r .= '</td><td id="tv_tree_right"></td></tr><tr><td id="tv_tree_bottomleft"></td><td id="tv_tree_bottom"></td><td id="tv_tree_bottomright"></td></tr></tbody></table>'; + return $r; + } + + /** + * Draw a person name preceded by sex icon, with parents as tooltip + * @param WT_Person $p a person + */ + private function drawPersonName($p) { + if ($this->allPartners) { + $f = $p->getPrimaryChildFamily(); + if ($f) { + switch ($p->getSex()) { + case 'M': + $title=' title="'.htmlspecialchars(strip_tags(/* I18N: e.g. "Son of [father name & mother name]" */ WT_I18N::translate('Son of %s', $f->getFullName()))).'"'; + break; + case 'F': + $title=' title="'.htmlspecialchars(strip_tags(/* I18N: e.g. "Daughter of [father name & mother name]" */ WT_I18N::translate('Daughter of %s', $f->getFullName()))).'"'; + break; + case 'U': + $title=' title="'.htmlspecialchars(strip_tags(/* I18N: e.g. "Child of [father name & mother name]" */ WT_I18N::translate('Child of %s', $f->getFullName()))).'"'; + break; + } + } else { + $title=''; + } + } + else + $title = ''; + $sex = $p->getSex(); + switch($sex) { + case 'M': + $sexSymbol = WT_UTF8_MALE; + break; + case 'F': + $sexSymbol = WT_UTF8_FEMALE; + break; + default: + $sexSymbol = WT_UTF8_NO_SEX; + break; + } + $r = '<div class="tv'.$sex.'"'.$title.'><span class="dates">'.$p->getLifeSpan().'</span><a href="'.$p->getHtmlUrl().'"><span class="tvSexSymbol tv'.$sex.' tv_link">'.$sexSymbol.'</span></a> '.$p->getFullName().'</div>'; + return $r; + } + + /** + * Get the thumbnail image for the given person + * + * @param Person $person + * @return string + */ + private function getThumbnail($personGroup, $person) { + global $MULTI_MEDIA, $SHOW_HIGHLIGHT_IMAGES; + + $thumbnail=""; + if ($MULTI_MEDIA && $SHOW_HIGHLIGHT_IMAGES) { + $object=$person->findHighlightedMedia(); + $img_title=PrintReady(htmlspecialchars($person->getFullName())); + if (!empty($object)) { + $mediaobject=WT_Media::getInstance($object['mid']); + $thumbnail=$mediaobject->displayMedia(array('display_type'=>'treeview','img_title'=>$img_title,'clearbox'=>'tvlb'.$personGroup->getXref())); + } else { + $thumbnail=display_silhouette(array('sex'=>$person->getSex(),'display_type'=>'treeview','img_title'=>$img_title)); // may return '' + } + } + + return $thumbnail; + } + + /** + * Draw a vertical line + * @param string order $order A parameter that set how to draw this line + * with auto-redimensionning capabilities + * WARNING : some tricky hacks are required in CSS to ensure cross-browser compliance + * some browsers shows an image, which imply a size limit in height, + * and some other browsers (ex: firefox) shows a <div> tag, which have no size limit in height + * Therefore, Firefox is a good choice to print very big trees. + */ + private function drawVerticalLine($order) { + $r = '<td class="tv_vline tv_vline_'.$order.'"><div class="tv_vline tv_vline_'.$order.'"></div></td>'; + return $r; + } + + /** + * Draw an horizontal line + */ + private function drawHorizontalLine() { + $r = '<td class="tv_hline"><div class="tv_hline"></div></td>'; + return $r; + } + +} + diff --git a/modules_v3/tree/css/styles/black/black.css b/modules_v3/tree/css/styles/black/black.css new file mode 100644 index 0000000000..9c47cd57a7 --- /dev/null +++ b/modules_v3/tree/css/styles/black/black.css @@ -0,0 +1,121 @@ +.tv_out { + background: #000; +} +/* Border (also have class table.tv_tree) */ +table#tvTreeBorder td#tv_tree_topleft { + background: url(treetopleft.gif); +} +table#tvTreeBorder td#tv_tree_top { + background: url(treetop.gif) repeat-x; +} +table#tvTreeBorder td#tv_tree_topright { + background: url(treetopright.gif); +} +table#tvTreeBorder td#tv_tree_left { + background: url(treeleft.gif) repeat-y; +} +table#tvTreeBorder td#tv_tree_right { + background: url(treeright.gif) repeat-y; +} +table#tvTreeBorder td#tv_tree_bottomleft { + background: url(treebottomleft.gif); +} +table#tvTreeBorder td#tv_tree_bottom { + background: url(treebottom.gif) repeat-x; +} +table#tvTreeBorder td#tv_tree_bottomright { + background: url(treebottomright.gif); +} +table#tvTreeBorder td#tv_tree_top div{ + font-family: fantasy; + font-size: 16px; + color: #4fff8f; +} +/* tree */ +table#tvTreeBorder td, #tv_tree { + background: #000; +} +#tv_tree div.tv_box .date{ + color: #dfdfff; +} +#tv_tree div.tv_box div.tvM { + background: #000012; + color: #efffff; +} +#tv_tree div.tv_box div.tvF { + background: #120000; + color: #ffefef; +} +#tv_tree div.tv_box a { + color: #4fff8f; +} +#tv_tree div.tv_box a:hover { + color: #df0000; +} + +/* horizontal and vertical lines color */ +#tv_tree div.tv_vline, #tv_tree div.tv_hline { + background-color: #8fdfaf; +} +#tv_tree table.tv_tree td.tv_vline_h { + background-image: url(vline.jpg); +} +#tv_tree table.tv_tree td.tv_vline_t { + background-image: url(vline_t.gif); +} +#tv_tree table.tv_tree td.tv_vline_b { + background-image: url(vline_b.gif); +} +/* Person or couple(s) box style */ +#tv_tree div.tv_box { + border: thin inset #00ffef; + background: #000; + border-radius: 2px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -khtml-border-radius: 2px; + box-shadow: 2px 2px 12px #2f8f4f; + -webkit-box-shadow: 2px 2px 12px #2f8f4f; + -moz-box-shadow: 2px 2px 12px #2f8f4f; + -khtml-box-shadow: 2px 2px 12px #2f8f4f; + filter: progid:DXImageTransform.Microsoft.dropShadow(color=#2f8f4f, offX=2, offY=2, positive=true); +} +#tv_tree div.tv_box span.tvM { + color: #00ffff; +} +#tv_tree div.tv_box span.tvF { + color: #ffef00; +} +/* The toolbox style. Button's images come from the active theme */ +#tv_tools, #tvStylesSubmenu { + background-color: #00af8f; + border: 1px outset #004f8f; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + box-shadow: 2px 2px 12px #2f8f4f; + -moz-box-shadow: 2px 2px 12px #2f8f4f; + -webkit-box-shadow: 2px 2px 12px #2f8f4f; + -khtml-box-shadow: 2px 2px 12px #2f8f4f; + filter: progid:DXImageTransform.Microsoft.dropShadow(color=#2f8f4f, offX=2, offY=2, positive=true); +} +#tv_tools li.tv_button { + border: thin solid #00af8f; + background-color: #00af8f; +} +#tv_tools li.tv_button:hover { + background: #8fefaf; + border: thin outset #00fffd; +} +#tv_tools li.tvPressed { + border: thin inset #008888; +} +#tvToolsHandler { + border: thin inset #004f8f; +} + +#tvToolsHandler:hover { + border: thin outset #004f8f; + background-color: #00ffaf; +}
\ No newline at end of file diff --git a/modules_v3/tree/css/styles/black/button.gif b/modules_v3/tree/css/styles/black/button.gif Binary files differnew file mode 100644 index 0000000000..9470561a4c --- /dev/null +++ b/modules_v3/tree/css/styles/black/button.gif diff --git a/modules_v3/tree/css/styles/black/treebottom.gif b/modules_v3/tree/css/styles/black/treebottom.gif Binary files differnew file mode 100644 index 0000000000..7e0b81e1cd --- /dev/null +++ b/modules_v3/tree/css/styles/black/treebottom.gif diff --git a/modules_v3/tree/css/styles/black/treebottomleft.gif b/modules_v3/tree/css/styles/black/treebottomleft.gif Binary files differnew file mode 100644 index 0000000000..0a4500c582 --- /dev/null +++ b/modules_v3/tree/css/styles/black/treebottomleft.gif diff --git a/modules_v3/tree/css/styles/black/treebottomright.gif b/modules_v3/tree/css/styles/black/treebottomright.gif Binary files differnew file mode 100644 index 0000000000..bd5fdfa35c --- /dev/null +++ b/modules_v3/tree/css/styles/black/treebottomright.gif diff --git a/modules_v3/tree/css/styles/black/treeleft.gif b/modules_v3/tree/css/styles/black/treeleft.gif Binary files differnew file mode 100644 index 0000000000..c79f398007 --- /dev/null +++ b/modules_v3/tree/css/styles/black/treeleft.gif diff --git a/modules_v3/tree/css/styles/black/treeright.gif b/modules_v3/tree/css/styles/black/treeright.gif Binary files differnew file mode 100644 index 0000000000..b1fb162550 --- /dev/null +++ b/modules_v3/tree/css/styles/black/treeright.gif diff --git a/modules_v3/tree/css/styles/black/treetop.gif b/modules_v3/tree/css/styles/black/treetop.gif Binary files differnew file mode 100644 index 0000000000..d08813ba7b --- /dev/null +++ b/modules_v3/tree/css/styles/black/treetop.gif diff --git a/modules_v3/tree/css/styles/black/treetopleft.gif b/modules_v3/tree/css/styles/black/treetopleft.gif Binary files differnew file mode 100644 index 0000000000..077ee16885 --- /dev/null +++ b/modules_v3/tree/css/styles/black/treetopleft.gif diff --git a/modules_v3/tree/css/styles/black/treetopright.gif b/modules_v3/tree/css/styles/black/treetopright.gif Binary files differnew file mode 100644 index 0000000000..1b7ad6d3c2 --- /dev/null +++ b/modules_v3/tree/css/styles/black/treetopright.gif diff --git a/modules_v3/tree/css/styles/black/vline.jpg b/modules_v3/tree/css/styles/black/vline.jpg Binary files differnew file mode 100644 index 0000000000..0d04b39433 --- /dev/null +++ b/modules_v3/tree/css/styles/black/vline.jpg diff --git a/modules_v3/tree/css/styles/black/vline_b.gif b/modules_v3/tree/css/styles/black/vline_b.gif Binary files differnew file mode 100644 index 0000000000..f4a8cab167 --- /dev/null +++ b/modules_v3/tree/css/styles/black/vline_b.gif diff --git a/modules_v3/tree/css/styles/black/vline_t.gif b/modules_v3/tree/css/styles/black/vline_t.gif Binary files differnew file mode 100644 index 0000000000..bfd7160ad0 --- /dev/null +++ b/modules_v3/tree/css/styles/black/vline_t.gif diff --git a/modules_v3/tree/css/styles/default/button.gif b/modules_v3/tree/css/styles/default/button.gif Binary files differnew file mode 100644 index 0000000000..2ea4932a0a --- /dev/null +++ b/modules_v3/tree/css/styles/default/button.gif diff --git a/modules_v3/tree/css/styles/default/default.css b/modules_v3/tree/css/styles/default/default.css new file mode 100644 index 0000000000..12da27556c --- /dev/null +++ b/modules_v3/tree/css/styles/default/default.css @@ -0,0 +1,61 @@ +/* Border (also have class table.tv_tree) */ +table#tvTreeBorder td#tv_tree_topleft { + background: none; +} +table#tvTreeBorder td#tv_tree_top { + background: none; +} +table#tvTreeBorder td#tv_tree_top div{ + font-family: Arial, Verdana, sans-serif; + font-size: 18px; +} +table#tvTreeBorder td#tv_tree_topright { + background: none; +} +table#tvTreeBorder td#tv_tree_left { + background: none; +} +table#tvTreeBorder td#tv_tree_right { + background: none; +} +table#tvTreeBorder td#tv_tree_bottomleft { + background: none; +} +table#tvTreeBorder td#tv_tree_bottom { + background: none; +} +table#tvTreeBorder td#tv_tree_bottomright { + background: none; +} +/* tree */ +table#tvTreeBorder td, #tv_tree { + background: none; +} +#tv_tree div.tv_box div.tvM, #tv_tree div.tv_box div.tvF { + background: none; + color: #000; +} +/* horizontal and vertical lines color */ +#tv_tree div.tv_vline, #tv_tree div.tv_hline { + background-color: #999; +} +#tv_tree table.tv_tree td.tv_vline_h { + background-image: url(vline.jpg); +} +#tv_tree table.tv_tree td.tv_vline_t { + background-image: url(vline_t.gif); +} +#tv_tree table.tv_tree td.tv_vline_b { + background-image: url(vline_b.gif); +} +/* Person or couple(s) box style */ +#tv_tree div.tv_box { + border: thin outset #000; +} +#tv_tree div.tv_box div.tvM, #tv_tree .tv_box div.tvF { + border: 0; + margin: 0; + padding: 0; + padding-left: 4px; + padding-right: 4px; +}
\ No newline at end of file diff --git a/modules_v3/tree/css/styles/default/vline.jpg b/modules_v3/tree/css/styles/default/vline.jpg Binary files differnew file mode 100644 index 0000000000..0bc05d5fac --- /dev/null +++ b/modules_v3/tree/css/styles/default/vline.jpg diff --git a/modules_v3/tree/css/styles/default/vline_b.gif b/modules_v3/tree/css/styles/default/vline_b.gif Binary files differnew file mode 100644 index 0000000000..78d660d161 --- /dev/null +++ b/modules_v3/tree/css/styles/default/vline_b.gif diff --git a/modules_v3/tree/css/styles/default/vline_t.gif b/modules_v3/tree/css/styles/default/vline_t.gif Binary files differnew file mode 100644 index 0000000000..de4f11226e --- /dev/null +++ b/modules_v3/tree/css/styles/default/vline_t.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/button.gif b/modules_v3/tree/css/styles/parchemin_gris/button.gif Binary files differnew file mode 100644 index 0000000000..a9b8543bf0 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/button.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/parchemin_gris.css b/modules_v3/tree/css/styles/parchemin_gris/parchemin_gris.css new file mode 100644 index 0000000000..b454df32a6 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/parchemin_gris.css @@ -0,0 +1,37 @@ +/* Border (also have class table.tv_tree) */ +table#tvTreeBorder td#tv_tree_topleft { + background: url(treetopleft.gif); +} +table#tvTreeBorder td#tv_tree_top { + background: url(treetop.gif) repeat-x; +} +table#tvTreeBorder td#tv_tree_topright { + background: url(treetopright.gif); +} +table#tvTreeBorder td#tv_tree_left { + background: url(treeleft.gif) repeat-y; +} +table#tvTreeBorder td#tv_tree_right { + background: url(treeright.gif) repeat-y; +} +table#tvTreeBorder td#tv_tree_bottomleft { + background: url(treebottomleft.gif); +} +table#tvTreeBorder td#tv_tree_bottom { + background: url(treebottom.gif) repeat-x; +} +table#tvTreeBorder td#tv_tree_bottomright { + background: url(treebottomright.gif); +} +table#tvTreeBorder td#tv_tree_top div{ + font-family: Comic Sans MS, cursive; + font-size: 18px; +} + +/* tree */ +#tv_tree { + background: url(tree.jpg); +} +#tv_tree div.tv_box div.tvM, #tv_tree div.tv_box div.tvF { + font-family: Comic Sans MS, cursive; +}
\ No newline at end of file diff --git a/modules_v3/tree/css/styles/parchemin_gris/tree.jpg b/modules_v3/tree/css/styles/parchemin_gris/tree.jpg Binary files differnew file mode 100644 index 0000000000..a313c0ac32 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/tree.jpg diff --git a/modules_v3/tree/css/styles/parchemin_gris/treebottom.gif b/modules_v3/tree/css/styles/parchemin_gris/treebottom.gif Binary files differnew file mode 100644 index 0000000000..44fd1c0974 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treebottom.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treebottomleft.gif b/modules_v3/tree/css/styles/parchemin_gris/treebottomleft.gif Binary files differnew file mode 100644 index 0000000000..a707bd5ca6 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treebottomleft.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treebottomright.gif b/modules_v3/tree/css/styles/parchemin_gris/treebottomright.gif Binary files differnew file mode 100644 index 0000000000..52e747cf79 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treebottomright.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treeleft.gif b/modules_v3/tree/css/styles/parchemin_gris/treeleft.gif Binary files differnew file mode 100644 index 0000000000..699aed79fe --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treeleft.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treeright.gif b/modules_v3/tree/css/styles/parchemin_gris/treeright.gif Binary files differnew file mode 100644 index 0000000000..ed032ce0d2 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treeright.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treetop.gif b/modules_v3/tree/css/styles/parchemin_gris/treetop.gif Binary files differnew file mode 100644 index 0000000000..d9f0c14c64 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treetop.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treetopleft.gif b/modules_v3/tree/css/styles/parchemin_gris/treetopleft.gif Binary files differnew file mode 100644 index 0000000000..7e9d5cb1aa --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treetopleft.gif diff --git a/modules_v3/tree/css/styles/parchemin_gris/treetopright.gif b/modules_v3/tree/css/styles/parchemin_gris/treetopright.gif Binary files differnew file mode 100644 index 0000000000..205a0b9bb9 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_gris/treetopright.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/button.gif b/modules_v3/tree/css/styles/parchemin_jauni/button.gif Binary files differnew file mode 100644 index 0000000000..f2c40a1f15 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/button.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/papier.jpg b/modules_v3/tree/css/styles/parchemin_jauni/papier.jpg Binary files differnew file mode 100644 index 0000000000..5d17a79758 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/papier.jpg diff --git a/modules_v3/tree/css/styles/parchemin_jauni/parchemin_jauni.css b/modules_v3/tree/css/styles/parchemin_jauni/parchemin_jauni.css new file mode 100644 index 0000000000..0a1afa9a03 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/parchemin_jauni.css @@ -0,0 +1,69 @@ +/* Border (also have class table.tv_tree) */ +table#tvTreeBorder td#tv_tree_topleft { + background: url(treetopleft.gif); +} +table#tvTreeBorder td#tv_tree_top { + background: url(treetop.gif) repeat-x; +} +table#tvTreeBorder td#tv_tree_top div{ + font-family: Times new Roman, Times, serif; + font-size: 18px; +} +table#tvTreeBorder td#tv_tree_topright { + background: url(treetopright.gif); +} +table#tvTreeBorder td#tv_tree_left { + background: url(treeleft.gif) repeat-y; +} +table#tvTreeBorder td#tv_tree_right { + background: url(treeright.gif) repeat-y; +} +table#tvTreeBorder td#tv_tree_bottomleft { + background: url(treebottomleft.gif); +} +table#tvTreeBorder td#tv_tree_bottom { + background: url(treebottom.gif) repeat-x; +} +table#tvTreeBorder td#tv_tree_bottomright { + background: url(treebottomright.gif); +} +/* tree */ +#tv_tree { + background: url(tree.jpg); +} +/* Person or couple(s) box style */ +#tv_tree div.tv_box { + border: thin outset #6f2f00; + border-radius: 8px; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + -khtml-border-radius: 8px; + box-shadow: 1px 1px 2px #cfcf8f; + -webkit-box-shadow: 1px 1px 2px #cfcf8f; + -moz-box-shadow: 1px 1px 2px #cfcf8f; + -khtml-box-shadow: 1px 1px 2px #dfdcfcf8ff00; + filter: progid:DXImageTransform.Microsoft.dropShadow(color=#cfcf8f, offX=1, offY=1, positive=true); +} +#tv_tree div.tv_box div.tvM, #tv_tree div.tv_box div.tvF { + font-family: Times new Roman, Times, serif; + font-size: 120%; + border-radius: 8px; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + -khtml-border-radius: 8px; + background: url(papier.jpg); + color: #180000; +} +/* horizontal and vertical lines color */ +#tv_tree div.tv_vline, #tv_tree div.tv_hline { + background-color: #002f6f; +} +#tv_tree table.tv_tree td.tv_vline_h { + background-image: url(vline.jpg); +} +#tv_tree table.tv_tree td.tv_vline_t { + background-image: url(vline_t.gif); +} +#tv_tree table.tv_tree td.tv_vline_b { + background-image: url(vline_b.gif); +}
\ No newline at end of file diff --git a/modules_v3/tree/css/styles/parchemin_jauni/tree.jpg b/modules_v3/tree/css/styles/parchemin_jauni/tree.jpg Binary files differnew file mode 100644 index 0000000000..65a11c6741 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/tree.jpg diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treebottom.gif b/modules_v3/tree/css/styles/parchemin_jauni/treebottom.gif Binary files differnew file mode 100644 index 0000000000..7b50105084 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treebottom.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treebottomleft.gif b/modules_v3/tree/css/styles/parchemin_jauni/treebottomleft.gif Binary files differnew file mode 100644 index 0000000000..dd695bc371 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treebottomleft.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treebottomright.gif b/modules_v3/tree/css/styles/parchemin_jauni/treebottomright.gif Binary files differnew file mode 100644 index 0000000000..5b55be458f --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treebottomright.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treeleft.gif b/modules_v3/tree/css/styles/parchemin_jauni/treeleft.gif Binary files differnew file mode 100644 index 0000000000..1a3e3b205a --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treeleft.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treeright.gif b/modules_v3/tree/css/styles/parchemin_jauni/treeright.gif Binary files differnew file mode 100644 index 0000000000..5af2d0f7dd --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treeright.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treetop.gif b/modules_v3/tree/css/styles/parchemin_jauni/treetop.gif Binary files differnew file mode 100644 index 0000000000..5a268d1b09 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treetop.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treetopleft.gif b/modules_v3/tree/css/styles/parchemin_jauni/treetopleft.gif Binary files differnew file mode 100644 index 0000000000..70616f7b0e --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treetopleft.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/treetopright.gif b/modules_v3/tree/css/styles/parchemin_jauni/treetopright.gif Binary files differnew file mode 100644 index 0000000000..e210b81557 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/treetopright.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/vline.jpg b/modules_v3/tree/css/styles/parchemin_jauni/vline.jpg Binary files differnew file mode 100644 index 0000000000..bb3d1ff5a2 --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/vline.jpg diff --git a/modules_v3/tree/css/styles/parchemin_jauni/vline_b.gif b/modules_v3/tree/css/styles/parchemin_jauni/vline_b.gif Binary files differnew file mode 100644 index 0000000000..7fc46853cb --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/vline_b.gif diff --git a/modules_v3/tree/css/styles/parchemin_jauni/vline_t.gif b/modules_v3/tree/css/styles/parchemin_jauni/vline_t.gif Binary files differnew file mode 100644 index 0000000000..3d53d0bf2c --- /dev/null +++ b/modules_v3/tree/css/styles/parchemin_jauni/vline_t.gif diff --git a/modules_v3/tree/css/styles/simple/button.gif b/modules_v3/tree/css/styles/simple/button.gif Binary files differnew file mode 100644 index 0000000000..88bf6b9690 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/button.gif diff --git a/modules_v3/tree/css/styles/simple/tree.jpg b/modules_v3/tree/css/styles/simple/tree.jpg Binary files differnew file mode 100644 index 0000000000..f9dc4568fe --- /dev/null +++ b/modules_v3/tree/css/styles/simple/tree.jpg diff --git a/modules_v3/tree/css/styles/simple/treebottom.gif b/modules_v3/tree/css/styles/simple/treebottom.gif Binary files differnew file mode 100644 index 0000000000..45cbf21e31 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treebottom.gif diff --git a/modules_v3/tree/css/styles/simple/treebottomleft.gif b/modules_v3/tree/css/styles/simple/treebottomleft.gif Binary files differnew file mode 100644 index 0000000000..28ab0e3b18 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treebottomleft.gif diff --git a/modules_v3/tree/css/styles/simple/treebottomright.gif b/modules_v3/tree/css/styles/simple/treebottomright.gif Binary files differnew file mode 100644 index 0000000000..854ad30506 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treebottomright.gif diff --git a/modules_v3/tree/css/styles/simple/treeleft.gif b/modules_v3/tree/css/styles/simple/treeleft.gif Binary files differnew file mode 100644 index 0000000000..4254f50bec --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treeleft.gif diff --git a/modules_v3/tree/css/styles/simple/treeright.gif b/modules_v3/tree/css/styles/simple/treeright.gif Binary files differnew file mode 100644 index 0000000000..8fea9e674e --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treeright.gif diff --git a/modules_v3/tree/css/styles/simple/treetop.gif b/modules_v3/tree/css/styles/simple/treetop.gif Binary files differnew file mode 100644 index 0000000000..980a027b88 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treetop.gif diff --git a/modules_v3/tree/css/styles/simple/treetopleft.gif b/modules_v3/tree/css/styles/simple/treetopleft.gif Binary files differnew file mode 100644 index 0000000000..b3666ec05f --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treetopleft.gif diff --git a/modules_v3/tree/css/styles/simple/treetopright.gif b/modules_v3/tree/css/styles/simple/treetopright.gif Binary files differnew file mode 100644 index 0000000000..c410879184 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/treetopright.gif diff --git a/modules_v3/tree/css/styles/simple/vline.jpg b/modules_v3/tree/css/styles/simple/vline.jpg Binary files differnew file mode 100644 index 0000000000..4138974ee0 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/vline.jpg diff --git a/modules_v3/tree/css/styles/simple/vline_b.gif b/modules_v3/tree/css/styles/simple/vline_b.gif Binary files differnew file mode 100644 index 0000000000..c29c4106d7 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/vline_b.gif diff --git a/modules_v3/tree/css/styles/simple/vline_t.gif b/modules_v3/tree/css/styles/simple/vline_t.gif Binary files differnew file mode 100644 index 0000000000..f37cf7d9f5 --- /dev/null +++ b/modules_v3/tree/css/styles/simple/vline_t.gif diff --git a/modules_v3/tree/css/tree.jpg b/modules_v3/tree/css/tree.jpg Binary files differnew file mode 100644 index 0000000000..f9dc4568fe --- /dev/null +++ b/modules_v3/tree/css/tree.jpg diff --git a/modules_v3/tree/css/treebottom.gif b/modules_v3/tree/css/treebottom.gif Binary files differnew file mode 100644 index 0000000000..45cbf21e31 --- /dev/null +++ b/modules_v3/tree/css/treebottom.gif diff --git a/modules_v3/tree/css/treebottomleft.gif b/modules_v3/tree/css/treebottomleft.gif Binary files differnew file mode 100644 index 0000000000..28ab0e3b18 --- /dev/null +++ b/modules_v3/tree/css/treebottomleft.gif diff --git a/modules_v3/tree/css/treebottomright.gif b/modules_v3/tree/css/treebottomright.gif Binary files differnew file mode 100644 index 0000000000..854ad30506 --- /dev/null +++ b/modules_v3/tree/css/treebottomright.gif diff --git a/modules_v3/tree/css/treeleft.gif b/modules_v3/tree/css/treeleft.gif Binary files differnew file mode 100644 index 0000000000..4254f50bec --- /dev/null +++ b/modules_v3/tree/css/treeleft.gif diff --git a/modules_v3/tree/css/treeright.gif b/modules_v3/tree/css/treeright.gif Binary files differnew file mode 100644 index 0000000000..8fea9e674e --- /dev/null +++ b/modules_v3/tree/css/treeright.gif diff --git a/modules_v3/tree/css/treetop.gif b/modules_v3/tree/css/treetop.gif Binary files differnew file mode 100644 index 0000000000..980a027b88 --- /dev/null +++ b/modules_v3/tree/css/treetop.gif diff --git a/modules_v3/tree/css/treetopleft.gif b/modules_v3/tree/css/treetopleft.gif Binary files differnew file mode 100644 index 0000000000..b3666ec05f --- /dev/null +++ b/modules_v3/tree/css/treetopleft.gif diff --git a/modules_v3/tree/css/treetopright.gif b/modules_v3/tree/css/treetopright.gif Binary files differnew file mode 100644 index 0000000000..c410879184 --- /dev/null +++ b/modules_v3/tree/css/treetopright.gif diff --git a/modules_v3/tree/css/treeview.css b/modules_v3/tree/css/treeview.css new file mode 100644 index 0000000000..14cbb8bb16 --- /dev/null +++ b/modules_v3/tree/css/treeview.css @@ -0,0 +1,335 @@ +/** CSS for TreeView module - Daniel Faivre, 2011 + * + * WARNING : DO NOT edit this file !!! To create a theme for the treeview module, + * just add in your theme's CSS file the properties you want to customize according to your theme + * All the properties that can be styled in your own theme are followed with the comment "customizable" + * CSS classes should allways be declared under their container to avoid unwanted side effects and speed-up CSS drawing. + * + * DO NOT change ANYTHING else : changing others parameters without extreme caution AND complete cross-browser validation DESTROY the tree design !!! + * + * Treeview styles: this module can print pretty big trees and offer different styles for the tree itself, for screen, printing, or both. + * Look at the embedded samples in the /treeview/css/styles directory to learn how to make your own tree styles. + */ + +.tv_out { + position: relative; + overflow: hidden; + height: 100%; + width: 100%; + border: thin solid #dfdfdf; /* customizable */ + min-height: 500px; /* customizable, not mandatory, but should be set to have allways something to display */ + max-height: 10000px; /* customizable, not mandatory, but should be set not too high to limit the size of ajax requests and not too low to enable whole big trees printing */ + /* background: #fffff8; /* customizable */ +} +.tv_out img { + border: 0; +} + +.tv_in { + clear: both; + position: relative; /* required for re-calculating size on ajax updates */ + left: 0; + top: 0; + cursor: move; + display: inline-block; /* prevent from blinking on IE */ +} +.tv_in table.tv_tree, .tv_in table.tv_tree tbody, .tv_in table.tv_tree tr, .tv_in table.tv_tree td { + border: 0 none; + padding: 0; + margin: 0; + background: none; +} +.tv_in table.tv_tree { + border-collapse: collapse; +} + +/* Border (also need, and have, class table.tv_tree) */ +table#tvTreeBorder td#tv_tree_topleft { + height: 50px; + width: 50px; + background: url(treetopleft.gif); /* customizable */ +} +table#tvTreeBorder td#tv_tree_top { + height: 50px; + text-align: center; + vertical-align: bottom; + background: url(treetop.gif) repeat-x; /* customizable */ +} +table#tvTreeBorder td#tv_tree_top div{ + font-family: Garamond, Times, serif; /* customizable */ + font-size: 16px; /* customizable */ +} +table#tvTreeBorder td#tv_tree_topright { + height: 50px; + width: 50px; + background: url(treetopright.gif); /* customizable */ +} +table#tvTreeBorder td#tv_tree_left { + width: 50px; + min-width: 50px; + background: url(treeleft.gif) repeat-y; /* customizable */ +} +table#tvTreeBorder td#tv_tree_right { + width: 50px; + min-width: 50px; + background: url(treeright.gif) repeat-y; /* customizable */ +} +table#tvTreeBorder td#tv_tree_bottomleft { + height: 50px; + width: 50px; + background: url(treebottomleft.gif); /* customizable */ +} +table#tvTreeBorder td#tv_tree_bottom { + height: 50px; + background: url(treebottom.gif) repeat-x; /* customizable */ +} +table#tvTreeBorder td#tv_tree_bottomright { + height: 50px; + width: 50px; + background: url(treebottomright.gif); /* customizable */ +} + +/* tree */ +#tv_tree { + background: url(tree.jpg); /* customizable */ +} +/* horizontal and vertical lines color */ +#tv_tree div.tv_vline, #tv_tree div.tv_hline { + background-color: #81A9CB; /* customizable : should be the same color than in background images of td.tv_vline_x */ +} + +/* TD container for a vertical line */ +#tv_tree table.tv_tree td.tv_vline { + width: 1px; + background-repeat: repeat-x; + background-position: 50% 50%; + height: 100%; /* required */ +} +#tv_tree table.tv_tree td.tv_vline_h { + background-image: url(vline.jpg); /* customizable : image color must be the same color than div.tv_vline and div.tv_hline */ +} +#tv_tree table.tv_tree td.tv_vline_t { + vertical-align: bottom; + background-image: url(vline_t.gif); /* customizable : image color must be the same color than div.tv_vline and div.tv_hline */ +} +#tv_tree table.tv_tree td.tv_vline_b { + vertical-align: top; + background-image: url(vline_b.gif); /* customizable : image color must be the same color than div.tv_vline and div.tv_hline */ +} +#tv_tree table.tv_tree td.tv_vline_c, .tv_in table.tv_tree td.tv_vline_h { + vertical-align: middle; +} +#tv_tree table.tv_tree td.tv_vline_c { + height: 1px; +} +/* vertical line drawing */ +#tv_tree table.tv_tree div.tv_vline { + width: 1px; +} +#tv_tree table.tv_tree div.tv_vline_t, #tv_tree table.tv_tree div.tv_vline_b { + height: 50%; +} +#tv_tree table.tv_tree div.tv_vline_c { + height: 1px; + overflow: hidden; /* required for IE */ +} +#tv_tree table.tv_tree div.tv_vline_h { + height: 100%; +} + +/* horizontal line drawing */ +#tv_tree td.tv_hline, #tv_tree div.tv_hline { + overflow: hidden; /* required for IE */ + width: 8px; /* customizable */ +} +#tv_tree div.tv_hline { + height: 1px; +} + +/* Person or couple(s) box style */ +#tv_tree div.tv_box { + border: thin outset #81A9CB; /* customizable */ + background: #fffdfd; /* customizable */ + margin-top: 2px; + margin-bottom: 2px; + padding: 0; + width: 180px; /* customizable: initial box width */ + cursor: help; /* customizable */ + border-collapse: collapse; /* required */ + border-radius: 4px; /* customizable */ + -moz-border-radius: 4px; /* customizable */ + -webkit-border-radius: 4px; /* customizable */ + -khtml-border-radius: 4px; /* customizable */ + box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + -webkit-box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + -moz-box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + -khtml-box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + filter: progid:DXImageTransform.Microsoft.dropShadow(color=#cfcfdf, offX=1, offY=1, positive=true); /* customizable */ +} +#tv_tree div.boxExpanded { + width: 250px; /* customizable: initial expanded box width */ +} +#tv_tree div.tv_box div.tvM { + background: #f5fdff; /* customizable */ + color: #220000; /* customizable */ +} +#tv_tree div.tv_box div.tvF { + background: #fff8f5; /* customizable */ + color: #000022; /* customizable */ +} +#tv_tree div.tv_box span.tvSexSymbol { + font-weight: bold; + font-family: x-large, serif; /*Arial Unicode MS, monospace; /* customizable, BUT test required for ALL browsers */ + vertical-align: top; + margin: 1px; +} +#tv_tree div.tv_box span.tvM { + color: #8f8fdf; /* customizable */ +} +#tv_tree div.tv_box span.tvF { + color: #df8f8f; /* customizable */ +} + +#tv_tree div.tv_box div.tvM, #tv_tree .tv_box div.tvF { + border: 0; + margin: 0; + padding: 1px; + padding-left: 4px; + padding-right: 4px; + border-radius: 4px; /* customizable */ + -moz-border-radius: 4px; /* customizable */ + -webkit-border-radius: 4px; /* customizable */ + -khtml-border-radius: 4px; /* customizable */ +} +#tv_tree div.tv_box i.dates { + float: right; + font-size: 75%; + margin-left: 4px; +} +#tv_tree div.tv_box img.tv_treelink { + height: 15px; + width: 15px; + float: right; +} +#tv_tree div.tv_box img.tv_box_loading { + height: 12px; + width: 12px; + margin: 2px; + float: right; +} +#tv_tree div.tv_box div.tv_person_expanded { + min-height: 50px; + padding: 2px; +} +#tv_tree div.tv_box img.pedigree_image_portrait, #tv_tree div.tv_box img.pedigree_image_landscape { + max-width: 50px; + _width: 50px; /* hack for IE versions that do not understand max-width */ + max-height: 50px; + margin: 2px; +} +#tv_tree div.tv_box div.tv_person_expanded a { + font-weight: bold; +} + +/* The toolbox style. Button's images come from the active theme */ +#tv_tools, #tvStylesSubmenu { + display: inline-block; + position: absolute; + left: 0; + top: 0; + padding: 0; + margin: 0; /* required */ + z-index: 90; /* should be < 100 because 100 is the z-index of WT menus */ + background-color: #efefef; /* customizable */ + border: 1px outset #dfdfdf; /* customizable */ + -moz-border-radius: 4px; /* customizable */ + -webkit-border-radius: 4px; /* customizable */ + -khtml-border-radius: 4px; /* customizable */ + border-radius: 4px; /* customizable */ + box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + -webkit-box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + -moz-box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + -khtml-box-shadow: 1px 1px 2px #cfcfdf; /* customizable */ + filter: progid:DXImageTransform.Microsoft.dropShadow(color=#cfcfdf, offX=1, offY=1, positive=true); /* customizable */ +} + +/* styles submenu */ +#tvStylesSubmenu { + display: none; + left: 0; + top: 0; + z-index: 91; /* just over tv_tools */ +} + +#tv_tools ul { + list-style: none; + margin: 0; + padding: 0; /* required */ +} +#tv_tools li.tv_button { + float: left; + position: relative; + padding: 0; /* required */ + margin: 0; + width: 24px; + height: 24px; + text-align: center; + vertical-align: middle; + border: thin solid #efefef; /* customizable */ + background-color: #efefef; /* customizable */ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} +#tvStylesSubmenu li.tv_button { + float : none; +} +#tv_tools li.tv_button a { + margin: 0; + display: block; +} +#tv_tools li.tv_button:hover { + background: #fffdfd; /* customizable */ + border: thin outset #fdfffd; /* customizable */ + cursor: pointer; +} +.tv_button a:hover, a:active { + background: #fffdfd; /* customizable */ +} +#tv_tools li.tvPressed { + border: thin inset #ffffff; /* customizable */ +} +#tv_tools ul li img { + border: none; + margin: 0; + padding: 0; + max-width: 22px; + max-height: 22px; + _width: 22px; /* hack for ie */ + _height: 22px; /* hack for ie */ + cursor: pointer; + text-align: center; + vertical-align: middle; +} +#tv_tools ul li a.help img.icon { + margin: 0; + margin-top: 3px; + padding: 0; + width: 15px; + height: 15px; +} + +#tvToolsHandler { + float: left; + cursor: move; + height: 22px; + width: 2px; + border: thin inset #f6f6f6; /* customizable */ + margin: 2px; + overflow: hidden; /* required for IE */ +} + +#tvToolsHandler:hover { + border: thin outset #f6f6f6; /* customizable */ +} diff --git a/modules_v3/tree/css/treeview_print.css b/modules_v3/tree/css/treeview_print.css new file mode 100644 index 0000000000..3723ce6732 --- /dev/null +++ b/modules_v3/tree/css/treeview_print.css @@ -0,0 +1,17 @@ +/** + * This file is a printing CSS for the TreeView module + * + * dF 2011 + */ + +#header, #tv_tools, #tv_tree div.tv_box img.tv_treelink, #tv_tree .default_thumbnail { + display : none; +} + +.tv_out { + top: 0; + left: 0; + border: 0 none; + overflow: visible; /* avoid cutting big trees by this html element */ + background: none; +}
\ No newline at end of file diff --git a/modules_v3/tree/css/vline.jpg b/modules_v3/tree/css/vline.jpg Binary files differnew file mode 100644 index 0000000000..4138974ee0 --- /dev/null +++ b/modules_v3/tree/css/vline.jpg diff --git a/modules_v3/tree/css/vline_b.gif b/modules_v3/tree/css/vline_b.gif Binary files differnew file mode 100644 index 0000000000..c29c4106d7 --- /dev/null +++ b/modules_v3/tree/css/vline_b.gif diff --git a/modules_v3/tree/css/vline_t.gif b/modules_v3/tree/css/vline_t.gif Binary files differnew file mode 100644 index 0000000000..f37cf7d9f5 --- /dev/null +++ b/modules_v3/tree/css/vline_t.gif diff --git a/modules_v3/tree/help_text.php b/modules_v3/tree/help_text.php new file mode 100644 index 0000000000..c340b17be8 --- /dev/null +++ b/modules_v3/tree/help_text.php @@ -0,0 +1,87 @@ +<?php +/** + * TreeView Module help text. + * + * This file is included from the application help_text.php script. + * It simply needs to set $title and $text for the help topic $help_topic + * + * webtrees: Web based Family History software + * Copyright (C) 2011 Daniel Faivre + * + * 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-1307 USA + * + * @version $Id$ + */ + +if (!defined('WT_WEBTREES')) { + header('HTTP/1.0 403 Forbidden'); + exit; +} + +$imgStyle = ' style="height: 22px; width: 22px; border: 0 none"'; +switch ($help) { + /* This help text need updating before it can be used. Too much embedded formatting, untranslated alt-text (do we need images here?), irrelevant mention of printing details (does a "printer" icon need help?), does "zoom in/out" really need help? +case 'TV_MODULE': + $title = WT_I18N::translate('Interactive tree'); + $text = WT_I18N::translate('An interactive tree showing all the ancestors and descendants of a person.'). + '<br /><br />'. + WT_I18N::translate('Commands').':'.'<br /><table><tbody>'. + '<tr><td><img src="'.$WT_IMAGES['zoomin'].'"'.$imgStyle.' alt="zoomin" /></td><td>'. + WT_I18N::translate('Zoom in : enlarge texts and person\'s boxes.').'</td></tr>'. + '<tr><td><img src="'.$WT_IMAGES['zoomout'].'"'.$imgStyle.' alt="zoomout" /></td><td>'. + WT_I18N::translate('Zoom out : reduce texts and person\'s boxes.').'</td></tr>'. + '<tr><td><img src="'.WT_MODULES_DIR.'/tree/images/zoom0.png"'.$imgStyle.' alt="nozoom" /></td><td>'. + WT_I18N::translate('No zoom.').'</td></tr>'. + '<tr><td><img src="'.$WT_IMAGES['ldarrow'].'"'.$imgStyle.'alt="alignLeft" /></td><td>'. + WT_I18N::translate('Align on top left corner. Useful before printing.').'</td></tr>'. + '<tr><td><img src="'.$WT_IMAGES['patriarch'].'"'.$imgStyle.' alt="center" /></td><td>'. + WT_I18N::translate('Center on the root person.').'</td></tr>'. + '<tr><td><img src="'.$WT_IMAGES['rdarrow'].'"'.$imgStyle.' alt="alignRight" /></td><td>'. + WT_I18N::translate('Align on top right corner.').'</td></tr>'. + '<tr><td><img src="'.WT_MODULES_DIR.'/tree/images/dates.png"'.$imgStyle.' alt="hide dates" /></td><td>'. + WT_I18N::translate('Hide/show dates on small boxes.').'</td></tr>'. + '<tr><td><img src="'.WT_MODULES_DIR.'/tree/images/compact.png"'.$imgStyle.' alt="c/e" /></td><td>'. + WT_I18N::translate('Compact tree / fixed boxes : switch beetween fixed-width boxes and compact tree. <i>fixed-width</i> display one generation\'s boxes in one column, and <i>compact</i> display more persons on the same area.').'</td></tr>'. + // function not enabled yet + // '<tr><td><img src="'.$WT_IMAGES['media'].'"'.$imgStyle.' alt="open" /></td><td>'. + // WT_I18N::translate('Open details for all displayed boxes. Could be long.').'</td></tr>'. + '<tr><td><img src="'.$WT_IMAGES["fambook"].'"'.$imgStyle.' alt="close" /></td><td>'. + WT_I18N::translate('Close all opened boxes.').'</td></tr>'. + '<tr><td><img src="'.WT_MODULES_DIR.'/tree/images/print.png"'.$imgStyle.' alt="print" /></td><td>'. + WT_I18N::translate('Download full resolution medias instead of thumbnails for opened person\'s boxes and open the print dialog when done.').'</td></tr>'. + '<tr><td><img src="'.$WT_IMAGES["sfamily"].'"'.$imgStyle.' alt="partners" /></td><td>'. + WT_I18N::translate('Show / hide multiples life partners or spouses.').'</td></tr>'. + '</tbody></table>'. + WT_I18N::translate(' +- when you drag, align or center the tree, person\'s boxes are loaded and added until the tree is completely loaded. + +- the treeview toolbar is draggable everywhere you want on the tree view. + +- you can directly access to an individual record with one click on a person\'s gender icon. + +- a click elsewhere on a family\'s box load and display more detailed informations about this family. When details are displayed, you can click on the tree icon beside a person\'s name to go to these person\'s interactive TreeView, or on the family\'s icon beside a life partner to go to these family\'s page. If the Lightbox module is enabled, a click on the person\'s thumbnail, when exists, open the associated image in the lightbox. When a person have some life partners, the lightbox display the main medias of these partners as a diaporama. + +- your preferences are stored in local cookies: zoom level, fixed or compact, switch last / all life partners, style. + +<u>Printing tips:</u> +- to print a big tree on one big sheet, you can set a big paper size and print in a file (you can find large format printing services almost everywhere). +- you can display details for the persons you want before printing the tree in a "What-You-See-Is-What-You-Get" mode. +- to print the lines between person boxes, enable the printing of background colors and images in your browser\'s settings. +- you can play with the TreeView zoom feature and the printing paper size setting to print any tree. +- if you encounter some printing issues on Linux systems, you can change the print-to-file driver, from lpr to kprinter (even if you don\'t use KDE). In Firefox, that is set in the "about:config" page. +'); + break; +*/ +} diff --git a/modules_v3/tree/images/alignLeft.png b/modules_v3/tree/images/alignLeft.png Binary files differnew file mode 100644 index 0000000000..104b6b5f1c --- /dev/null +++ b/modules_v3/tree/images/alignLeft.png diff --git a/modules_v3/tree/images/alignRight.png b/modules_v3/tree/images/alignRight.png Binary files differnew file mode 100644 index 0000000000..3f2a81092f --- /dev/null +++ b/modules_v3/tree/images/alignRight.png diff --git a/modules_v3/tree/images/center.png b/modules_v3/tree/images/center.png Binary files differnew file mode 100644 index 0000000000..5e70627b6b --- /dev/null +++ b/modules_v3/tree/images/center.png diff --git a/modules_v3/tree/images/compact.png b/modules_v3/tree/images/compact.png Binary files differnew file mode 100644 index 0000000000..07b092d1ed --- /dev/null +++ b/modules_v3/tree/images/compact.png diff --git a/modules_v3/tree/images/dates.png b/modules_v3/tree/images/dates.png Binary files differnew file mode 100644 index 0000000000..f358f9057f --- /dev/null +++ b/modules_v3/tree/images/dates.png diff --git a/modules_v3/tree/images/print.png b/modules_v3/tree/images/print.png Binary files differnew file mode 100644 index 0000000000..c1dad25728 --- /dev/null +++ b/modules_v3/tree/images/print.png diff --git a/modules_v3/tree/images/zoom0.png b/modules_v3/tree/images/zoom0.png Binary files differnew file mode 100644 index 0000000000..9a30355549 --- /dev/null +++ b/modules_v3/tree/images/zoom0.png diff --git a/modules_v3/tree/js/treeview.js b/modules_v3/tree/js/treeview.js new file mode 100644 index 0000000000..79bf2e244b --- /dev/null +++ b/modules_v3/tree/js/treeview.js @@ -0,0 +1,568 @@ +/** + * Class TreeViewHandler + * (c) Daniel Faivre 2011 + * + * Tips : + * - for loops are much faster than using each + * - return false is required in functions + */ +function TreeViewHandler(treeviewInstance, allPartners, nbStyles) { + this.treeview = jQuery("#" + treeviewInstance + "_in"); + this.loadingImage = jQuery("#" + treeviewInstance + "_loading"); + this.toolbox = jQuery("#tv_tools"); + this.buttons = jQuery(".tv_button:first", this.toolbox); + this.toolboxOrientation = (this.toolbox.find("#tvToolsHandler").css("float") != "left") ? 'v' : 'h'; + this.nbStyles = nbStyles; + this.zoom = 100; // in percent + this.boxWidth = this.treeview.find(".tv_box:first").width(); // store the initial box width + if (isNaN(this.boxWidth)) + this.boxWidth = 180; // default family box width + this.boxExpandedWidth = 250; // default expanded family box width + this.cookieDays = 360; // lifetime of preferences memory, in days + this.ajaxUrl = "module.php?mod=tree&instance=" + treeviewInstance + + "&allPartners=" + (allPartners ? "true" : "false") + + "&mod_action="; + + this.container = this.treeview.parent(); // Store the container element ("#" + treeviewInstance + "_out") + this.auto_box_width = false; + this.showDates = true; + this.updating = false; + this.overLevel = 0; // internal var for handling submenus + + var tv = this; // Store "this" for usage within jQuery functions where "this" is not this ;-) + + // Restore user preferences + if (readCookie("zoom") != null) { + tv.setZoom(parseInt(readCookie("zoom")) / 100); + } + if (readCookie("compact") == "true") { + tv.compact(); + } + // set/reset the cookie allPartners + if (readCookie("allPartners") != allPartners) + createCookie("allPartners", allPartners, this.cookieDays); + + // Define the draggables + tv.toolbox.draggable({ + handle: "#tvToolsHandler", + cursor: "move", + containment: "#" + treeviewInstance + "_out", + snap: "#" + treeviewInstance + "_out", + snapMode: "inner", + snapTolerance: 10 + }); + tv.treeview.draggable({ + cursor: "move", + stop: function(event, ui) { + tv.updateTree(); + } + }); + + // define the toolbox submenu's functions + tv.toolbox.find("#tvStyleButton,#tvStylesSubmenu").each(function(index, tvStyleButton) { + var submenu = tv.toolbox.find("#tvStylesSubmenu"); + tvStyleButton.onmouseover = function() { + tv.overLevel++; + var bw = tv.buttons.outerWidth(true); + var bm = (tv.buttons.outerWidth(true) - tv.buttons.outerWidth()) / 2; + if (tv.toolboxOrientation != 'v') { + var deltaX = 6 + 8 * bw; // align with the 8th button + var deltaY = bw; + } + else { + var deltaX = bw; + var deltaY = 6 + 8 * (bw-bm); // align with the 8th button + } + submenu.css("left", deltaX); + submenu.css("top", deltaY); + submenu.css("display", "block"); + } + tvStyleButton.onmouseout = function() { + tv.overLevel--; + window.setTimeout(function(){if (tv.overLevel < 1) jQuery(submenu).css("display", "none");}, 200); + } + }); + // Add click handlers to buttons + tv.toolbox.find("#tvToolsHandler").each(function(index, tvthandler) { + tvthandler.ondblclick = function() { + //tv.changeToolsOrientation(); + var toolbox = "#tvToolsHandler, li.tv_button"; + var submenu = tv.toolbox.find("#tvStylesSubmenu"); + if (tv.toolbox.find(toolbox).css("float") == "left") { + tv.toolbox.find(toolbox).css("float", "none"); + submenu.css("width", tv.nbStyles * tv.buttons.outerWidth(true)); + submenu.find("li.tv_button").css("float", "left"); + jQuery("#tvToolsHandler", tv.toolbox).css("height", "2px").css("width", "22px"); + tv.toolboxOrientation = 'v'; + } + else { + tv.toolbox.find(toolbox).css("float", "left"); + submenu.css("width", tv.buttons.outerWidth(true)); + submenu.find("li.tv_button").css("float", "none"); + jQuery("#tvToolsHandler", tv.toolbox).css("height", "22px").css("width", "2px"); + tv.toolboxOrientation = 'h'; + } + return false; + } + }); + tv.toolbox.find("#tvbZoomIn").each(function(index, tvbZoomIn) { + tvbZoomIn.onclick = function() { + tv.setZoom(1.1, tvbZoomIn); + } + }); + tv.toolbox.find("#tvbZoomOut").each(function(index, tvbZoomOut) { + tvbZoomOut.onclick = function() { + tv.setZoom(0.9, tvbZoomOut); + } + }); + tv.toolbox.find("#tvbNoZoom").each(function(index, tvbNoZoom) { + tvbNoZoom.onclick = function() { + tv.setZoom(0, tvbNoZoom); + } + }); + tv.toolbox.find("#tvbLeft").each(function(index, tvLeft) { + var b = jQuery(tvLeft, tv.toolbox); + tvLeft.onclick = function() { + b.addClass("tvPressed"); + tv.align("left", b); + } + }); + tv.toolbox.find("#tvbCenter").each(function(index, tvCenter) { + tvCenter.onclick = function() { + tv.centerOnRoot(); + } + }); + tv.toolbox.find("#tvbRight").each(function(index, tvRight) { + var b = jQuery(tvRight, tv.toolbox); + tvRight.onclick = function() { + b.addClass("tvPressed"); + tv.align("right", b); + } + }); + tv.toolbox.find("#tvbDates").each(function(index, tvbDates) { + var b = jQuery(tvbDates, tv.toolbox); + tvbDates.onclick = function() { + if (tv.showDates) { + s = 'none'; + b.removeClass("tvPressed"); + tv.showDates = false; + } + else { + s = 'inline'; + b.addClass("tvPressed"); + tv.showDates = true; + } + tv.treeview.find(".tv_box .dates").css("display", s); + } + }); + tv.toolbox.find("#tvbCompact").each(function(index, tvCompact) { + tvCompact.onclick = function() { + tv.compact(); + } + }); + tv.toolbox.find("#tvbPrint").each(function(index, tvbPrint) { + tvbPrint.onclick = function() { + tv.print(tvbPrint); + } + }); + tv.toolbox.find("#tvbOpen").each(function(index, tvbOpen) { + var b = jQuery(tvbOpen, tv.toolbox); + tvbOpen.onclick = function() { + b.addClass("tvPressed"); + tv.setLoading(); + var e = jQuery.Event("click"); + tv.treeview.find(".tv_box:not(.boxExpanded)").each(function(index, box){ + var pos = jQuery(box, tv.treeview).offset(); + if ((pos.left >= tv.leftMin) && (pos.left <= tv.leftMax) && (pos.top >= tv.topMin) && (pos.top <= tv.topMax)) + tv.expandBox(box,e); + }); + b.removeClass("tvPressed"); + tv.setComplete(); + } + }); + tv.toolbox.find("#tvbClose").each(function(index, tvbClose) { + var b = jQuery(tvbClose,tv.toolbox ); + tvbClose.onclick = function() { + b.addClass("tvPressed"); + tv.setLoading(); + tv.treeview.find(".tv_box.boxExpanded").each(function(index, box){ + jQuery(box).css("display", "none").removeClass("boxExpanded").parent().find(".tv_box.collapsedContent").css("display", "block"); + }); + b.removeClass("tvPressed"); + tv.setComplete(); + } + }); + + // Intercept the scroll event to keep the toolbox available + jQuery(window).scroll(function(){ + if (jQuery(window).scrollTop() > tv.container.offset().top) + tv.toolbox.css("position", "fixed"); + else + tv.toolbox.css("position", "absolute"); + }); + + tv.centerOnRoot(); // fire ajax update if needed, which call setComplete() when all is loaded + return false; +} +/** + * Class TreeView setLoading method + */ +TreeViewHandler.prototype.setLoading = function() { + this.treeview.css("cursor", "wait"); + this.loadingImage.css("display", "block"); +} +/** + * Class TreeView setComplete method + */ +TreeViewHandler.prototype.setComplete = function() { + this.treeview.css("cursor", "move"); + this.loadingImage.css("display", "none"); +} + +/** + * Class TreeView getSize method + * Store the viewport current size + */ +TreeViewHandler.prototype.getSize = function() { + var tv = this; + // retrieve the current container bounding box + var container = tv.container.parent(); + var offset = container.offset(); + tv.leftMin = offset.left; + tv.leftMax = tv.leftMin + container.innerWidth(); + tv.topMin = offset.top; + tv.topMax = tv.topMin + container.innerHeight(); + /* + var frm = jQuery("#tvTreeBorder"); + tv.treeview.css("width", frm.width()); + tv.treeview.css("height", frm.height());*/ +} + +/** + * Class TreeView updateTree method + * Perform ajax requests to complete the tree after drag + * param boolean @center center on root person when done + */ +TreeViewHandler.prototype.updateTree = function(center, button) { + var tv = this; // Store "this" for usage within jQuery functions where "this" is not this ;-) + var toLoad = new Array(); + var elts = new Array(); + this.getSize(); + + // check which td with datafld attribute are within the container bounding box + // and therefore need to be dynamically loaded + tv.treeview.find("td[abbr]").each(function(index, el) { + el = jQuery(el, tv.treeview); + var pos = el.offset(); + if ((pos.left >= tv.leftMin) && (pos.left <= tv.leftMax) && (pos.top >= tv.topMin) && (pos.top <= tv.topMax)) { + toLoad.push(el.attr("abbr")); + elts.push(el); + } + }); + // if some boxes need update, we perform an ajax request + if (toLoad.length > 0) { + tv.updating = true; + tv.setLoading(); + jQuery.ajax({ + url: tv.ajaxUrl + "getPersons", + dataType: "json", + data: "q=" + toLoad.join(";"), + success: function(ret) { + var nb = elts.length; + var rootEl = jQuery(".rootPerson", this.treeview); + var l = rootEl.offset().left; + for (var i=0;i<nb;i++) { + elts[i].removeAttr("abbr").html(ret[i]); + } + // repositionning + tv.treeview.offset({left: tv.treeview.offset().left - rootEl.offset().left +l}); + // we now ajust the draggable treeview size to its content size + tv.getSize(); + }, + complete: function() { + if (tv.treeview.find("td[abbr]").length) + tv.updateTree(center, button); // recursive call + // the added boxes need that in mode compact boxes + if (tv.auto_box_width) + tv.treeview.find(".tv_box").css("width", "auto"); + tv.updating = true; // avoid an unuseful recursive call when all requested persons are loaded + if (center == true) + tv.centerOnRoot(); + if (button) + button.removeClass("tvPressed"); + tv.setComplete(); + tv.updating = false; + }, + timeout: function() { + if (button) + button.removeClass("tvPressed"); + tv.updating = false; + tv.setComplete(); + } + }); + } + else { + if (button) + button.removeClass("tvPressed"); + tv.setComplete(); + } + return false; +} + +/** + * Class TreeView setZoom method + */ +TreeViewHandler.prototype.setZoom = function(zoom, button) { + this.treeview.css("cursor", "wait"); + jQuery(button).addClass("tvPressed"); + if (zoom == 0) + this.zoom = 100; + else + this.zoom *= zoom; + this.treeview.css("font-size", this.zoom + "%"); + + // we zoom the person boxes only if boxes width is fixed + if (!this.auto_box_width) { + jQuery(".tv_box:not(.expanded)", this.treeview).css("width", this.boxWidth * (this.zoom / 100) + "px"); + jQuery(".boxExpanded", this.treeview).css("width", this.boxExpandedWidth * (this.zoom / 100) + "px"); + } + createCookie("zoom", this.zoom.toString(), this.cookieDays); + jQuery(button).removeClass("tvPressed"); + this.treeview.css("cursor", "move"); + return false; +} + +/** + * Class TreeView compacte method + */ +TreeViewHandler.prototype.compact = function() { + var tv = this; + var b = jQuery("#tvbCompact", tv.toolbox); + tv.setLoading(); + if (!tv.auto_box_width) { + tv.treeview.find(".tv_box").css("width", "auto"); + tv.auto_box_width = true; + if (!readCookie("compact")) + createCookie("compact", true, tv.cookieDays); + if (!tv.updating) + tv.updateTree(); + b.addClass("tvPressed"); + } + else { + var w = tv.boxWidth * (tv.zoom / 100) + "px"; + var ew = tv.boxExpandedWidth * (tv.zoom / 100) + "px"; + tv.treeview.find(".tv_box:not(boxExpanded)", tv.treeview).css("width", w); + tv.treeview.find(".boxExpanded", tv.treeview).css("width", ew); + tv.auto_box_width = false; + if (readCookie("compact")) + createCookie("compact", false, tv.cookieDays); + b.removeClass("tvPressed"); + } + tv.setComplete(); + return false; +} + + +/** + * Class TreeView align method + */ +TreeViewHandler.prototype.align = function(alignment, button) { + this.setLoading(); + switch (alignment) { + case "left": + this.treeview.offset({left: this.container.offset().left, top: this.container.offset().top}); + break; + case "right": + this.treeview.offset({left: this.container.offset().left + this.container.width() - this.treeview.width(), top: this.container.offset().top}); + break; + default: + return false; + } + if (!this.updating) + this.updateTree(false, button); + return false; +} + +/** + * Class TreeView centerOnRoot method + */ +TreeViewHandler.prototype.centerOnRoot = function() { + this.loadingImage.css("display", "block"); + var tvc = this.container; + var tvcW = tvc.innerWidth() / 2; + if(isNaN(tvcW)) + return false; + var tvcH = tvc.innerHeight() / 2; + var el = jQuery(".rootPerson", this.treeview); + var dLeft = tvc.offset().left + this.treeview.offset().left + tvcW - el.offset().left - el.outerWidth()/2; + var dTop = tvc.offset().top + this.treeview.offset().top + tvcH - el.offset().top - el.outerHeight()/2; + this.treeview.offset({left: dLeft, top: dTop}); + + if (!this.updating) + this.updateTree(true); + return false; +} + +/** + * Class TreeView style method + * param string @style the style directory + */ +TreeViewHandler.prototype.style = function(stylepath, style, el) { + jQuery("#tvCSS").remove(); + jQuery("#tvStylesSubmenu .tv_button").removeClass("tvPressed"); + if (style) + jQuery("head").append('<link id="tvCSS" rel="stylesheet" type="text/css" href="' + stylepath + style + '/' + style + '.css">'); + jQuery(el).parent().addClass("tvPressed"); + jQuery("#tvStyleButton").html(jQuery(el).clone()); + createCookie("tvStyle", style, this.cookieDays) +} + +/** + * Class TreeView expandBox method + * param string @box the person box element + * param string @event the call event + * param string @pid the person id + * + * called ONLY for elements which have NOT the class tv_link to avoid unuseful requests to the server + */ +TreeViewHandler.prototype.expandBox = function(box, event) { + var t = jQuery(event.target); + if (t.hasClass("tv_link")) + return false; + + var box = jQuery(box, this.treeview); + var bc = box.parent(); // bc is Box Container + var pid = box.attr("abbr"); + var tv = this; // Store "this" for usage within jQuery functions where "this" is not this ;-) + var expanded; + var collapsed; + + if (bc.hasClass("detailsLoaded")) { + collapsed = bc.find(".collapsedContent"); + expanded = bc.find(".tv_box:not(.collapsedContent)"); + } + else { + // Cache the box content as an hidden person's box in the box's parent element + expanded = box; + collapsed = box.clone(); + bc.append(collapsed.addClass("collapsedContent").css("display", "none")); + // we add a waiting image at the right side of the box + // TODO : manage rtl (left side instead of right in rtl mode) + var loadingImage = this.loadingImage.find("img").clone().addClass("tv_box_loading").css("display", "block"); + box.prepend(loadingImage); + tv.updating = true; + tv.setLoading(); + // perform the Ajax request and load the result in the box + box.load(tv.ajaxUrl + "getDetails&pid=" + pid, function() { + // If Lightbox module is active, we reinitialize it for the new links + if (typeof CB_Init == "function") { + CB_Init(); + } + box.css("width", tv.boxExpandedWidth * (tv.zoom / 100) + "px"); + loadingImage.remove(); + bc.addClass("detailsLoaded"); + tv.setComplete(); + tv.updating = false; + }); + } + if (box.hasClass("boxExpanded")) { + expanded.css("display", "none"); + collapsed.css("display", "block"); + box.removeClass("boxExpanded"); + } + else { + expanded.css("display", "block"); + collapsed.css("display", "none"); + expanded.addClass("boxExpanded"); + } + // we must ajust the draggable treeview size to its content size + this.getSize(); + return false; +} + +/** + * Class TreeView print method :load full resolution medias for opened details boxes, and open the print dialog after + */ +TreeViewHandler.prototype.print = function() { + var tv = this; + var medias = this.treeview.find(".boxExpanded .pedigree_image_portrait, .boxExpanded .pedigree_image_landscape").not(".HiRes"); + if (medias.length) { + var ml = new Array(); + tv.img2load = new Array(); + medias.each(function(index, media) { + var alt = jQuery(media).attr("alt"); + if (alt.length) { + ml.push(jQuery(media).attr("alt")); + tv.img2load.push(media); + } + }); + tv.updating = true; + tv.setLoading(); + jQuery.ajax({ + url: tv.ajaxUrl + "getMedias", + dataType: "json", + data: "q=" + ml.join(";"), + success: function(ret) { + var nb = tv.img2load.length; + for (var i=0;i<nb;i++) { + tv.img2load[i].src = ret[i]; + } + }, + complete: function() { + tv.printWhenLoaded(); + }, + timeout: function() { + tv.updating = false; + tv.setComplete(); + } + }); + } + else + window.print(); +} + +/** + * Class TreeView printIfLoaded method :a callback function called when loading medias is pending + */ +TreeViewHandler.prototype.printWhenLoaded = function() { + var tv = this; + var nb = nbImg = tv.img2load.length; + for (var i=0;i<nbImg;i++) { + if (tv.img2load[i].complete) { + jQuery(tv.img2load[i]).addClass("HiRes"); + nb--; + } + } + if (nb > 0) + window.setTimeout(tv.printWhenLoaded(), 200); + tv.setComplete(); + tv.updating = false; + window.print(); +} + +function createCookie(name,value,days) { + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + var expires = "; expires="+date.toGMTString(); + } + else var expires = ""; + document.cookie = name+"="+value+expires+"; path=/"; +} + +function readCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') + c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) + return c.substring(nameEQ.length,c.length); + } + return null; +} + +function eraseCookie(name) { + createCookie(name,"",-1); +} diff --git a/modules_v3/tree/module.php b/modules_v3/tree/module.php new file mode 100644 index 0000000000..0ff810b229 --- /dev/null +++ b/modules_v3/tree/module.php @@ -0,0 +1,157 @@ +<?php +// TreeView module class +// +// Tip : you could change the number of generations loaded before ajax calls both in individual page and in treeview page to optimize speed and server load +// +// Copyright (C) 2011 webtrees development team +// +// 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-1307 USA +// +// $Id$ + +if (!defined('WT_WEBTREES')) { + header('HTTP/1.0 403 Forbidden'); + exit; +} + +class tree_WT_Module extends WT_Module implements WT_Module_Tab { + var $headers; // CSS and script to include in the top of <head> section, before theme's CSS + var $style; // the name of the active style, or false + var $css; // a customized CSS to load AFTER theme's CSS if $style is defined + var $js; // the TreeViewHandler javascript + + function __construct() { + // define the module inclusions for the page header + $this->headers = '<link rel="stylesheet" type="text/css" href="'.WT_MODULES_DIR.$this->getName().'/css/treeview.css" />'; + $this->js = '<script type="text/javascript" language="javascript" src="'.WT_MODULES_DIR.$this->getName().'/js/treeview.js"></script>'; + + // Retrieve the user's personalized style + if (isset($_COOKIE['tvStyle'])) { + $this->style = $_COOKIE['tvStyle']; + $this->css = '<link id="tvCSS" rel="stylesheet" type="text/css" href="'.WT_MODULES_DIR.$this->getName().'/css/styles/'.$this->style.'/'.$this->style.'.css" />'; + } + else { + $this->style = false; + $this->css = ''; + } + $this->css .= '<link rel="stylesheet" type="text/css" href="'.WT_MODULES_DIR.$this->getName().'/css/treeview_print.css" media="print" />'; + } + + // Extend WT_Module. This title should be normalized when this module will be added officially + public function getTitle() { + return /* I18N: Name of a module */ WT_I18N::translate('Interactive tree'); + } + + // Extend WT_Module + public function getDescription() { + return /* I18N: Description of the "Interactive tree" module */ WT_I18N::translate('An interactive tree, showing all the ancestors and descendants of a person.'); + } + + // Implement WT_Module_Tab + public function defaultTabOrder() { + return 68; + } + + // Implement WT_Module_Tab + public function getJSCallback() { + return ''; +} + + // Implement WT_Module_Tab + public function getTabContent() { + require_once WT_MODULES_DIR.$this->getName().'/class_treeview.php'; + $tv = new TreeView('tvTab'); + $r = $tv->drawViewport($this->controller->pid, 3, $this->style); + return $r; + } + + // Implement WT_Module_Tab + public function hasTabContent() { + return true; + } + // Implement WT_Module_Tab + public function isGrayedOut() { + return false; + } + // Implement WT_Module_Tab + public function canLoadAjax() { + return true; + } + + // Implement WT_Module_Tab + public function getPreLoadContent() { + // a workaround to the lack of a proper method of class Module to insert css and scripts in <head> where needed + // the required loading order is : headers, theme, css + return $this->js.'<script language="javascript" type="text/javascript">jQuery("head").prepend(\''.$this->headers.'\').append(\''.$this->css.'\');</script>'; + } + + // Extend WT_Module + // We define here actions to proceed when called, either by Ajax or not + public function modAction($mod_action) { + require_once WT_MODULES_DIR.$this->getName().'/class_treeview.php'; + switch($mod_action) { + case 'treeview': + $tvName = 'tv'; + $rootid = safe_GET('rootid'); + $rootid = check_rootid($rootid); + $tv = new TreeView('tv'); + ob_start(); + $person=WT_Person::getInstance($rootid); + print_header(WT_I18N::translate('Interactive tree of %s', $person->getFullName())); + if (WT_USE_LIGHTBOX) { + require WT_MODULES_DIR.'lightbox/functions/lb_call_js.php'; + } + $header = ob_get_clean(); + // we do this trick to insert headers js calls and css + // should be improved as soon as webtrees will have provided a way to do that + // in a more proper way (a method of Module object to insert its css and scripts calls in the <head>) + // The CSS inserted here could be overided by cascading style sheet mechanism + // when relevant properties are defined in the theme's CSS + $header = str_replace('<head>', '<head>'.$this->headers, $header); + // If TreeView was personalized, include the custom CSS at the end of the header, to "cascade" previously loaded CSS + $header = str_replace('</head>', $this->js.$this->css.'</head>', $header); + echo $header; + echo $tv->drawViewport($rootid, 4, $this->style); + print_footer(); + break; + + case 'getDetails': + header('Content-Type: text/html; charset=UTF-8'); + $pid = safe_GET('pid'); + $i = safe_GET('instance'); + $tv = new TreeView($i); + echo $tv->getDetails($pid); + break; + + case 'getPersons': + $q = $_REQUEST["q"]; + $i = safe_GET('instance'); + $tv = new TreeView($i); + echo $tv->getPersons($q); + break; + + // dynamically load full medias instead of thumbnails for opened boxes before printing + case 'getMedias': + $q = $_REQUEST["q"]; + $i = safe_GET('instance'); + $tv = new TreeView($i); + echo $tv->getMedias($q); + break; + + default: + header('HTTP/1.0 404 Not Found'); + } + } +} |
