dbda8d6ce9 2007-07-21 drh: /* 5cd9597428 2007-09-24 jnc: ** Copyright (c) 2006,2007 D. Richard Hipp dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is free software; you can redistribute it and/or dbda8d6ce9 2007-07-21 drh: ** modify it under the terms of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License version 2 as published by the Free Software Foundation. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is distributed in the hope that it will be useful, dbda8d6ce9 2007-07-21 drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of dbda8d6ce9 2007-07-21 drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dbda8d6ce9 2007-07-21 drh: ** General Public License for more details. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** You should have received a copy of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License along with this library; if not, write to the dbda8d6ce9 2007-07-21 drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, dbda8d6ce9 2007-07-21 drh: ** Boston, MA 02111-1307, USA. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Author contact information: dbda8d6ce9 2007-07-21 drh: ** drh@hwaci.com dbda8d6ce9 2007-07-21 drh: ** http://www.hwaci.com/drh/ dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ******************************************************************************* dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This file contains code to implement the basic web page look and feel. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: #include "config.h" dbda8d6ce9 2007-07-21 drh: #include "style.h" dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Elements of the submenu are collected into the following dbda8d6ce9 2007-07-21 drh: ** structure and displayed below the main menu by style_header(). dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Populate this structure with calls to style_submenu_element() dbda8d6ce9 2007-07-21 drh: ** prior to calling style_header(). dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: static struct Submenu { dbda8d6ce9 2007-07-21 drh: const char *zLabel; dbda8d6ce9 2007-07-21 drh: const char *zTitle; dbda8d6ce9 2007-07-21 drh: const char *zLink; dbda8d6ce9 2007-07-21 drh: } aSubmenu[30]; dbda8d6ce9 2007-07-21 drh: static int nSubmenu = 0; dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Add a new element to the submenu dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void style_submenu_element( dbda8d6ce9 2007-07-21 drh: const char *zLabel, dbda8d6ce9 2007-07-21 drh: const char *zTitle, dbda8d6ce9 2007-07-21 drh: const char *zLink dbda8d6ce9 2007-07-21 drh: ){ dbda8d6ce9 2007-07-21 drh: assert( nSubmenu < sizeof(aSubmenu)/sizeof(aSubmenu[0]) ); dbda8d6ce9 2007-07-21 drh: aSubmenu[nSubmenu].zLabel = zLabel; dbda8d6ce9 2007-07-21 drh: aSubmenu[nSubmenu].zTitle = zTitle; dbda8d6ce9 2007-07-21 drh: aSubmenu[nSubmenu].zLink = zLink; dbda8d6ce9 2007-07-21 drh: nSubmenu++; dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Compare two submenu items for sorting purposes dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: static int submenuCompare(const void *a, const void *b){ dbda8d6ce9 2007-07-21 drh: const struct Submenu *A = (const struct Submenu*)a; dbda8d6ce9 2007-07-21 drh: const struct Submenu *B = (const struct Submenu*)B; dbda8d6ce9 2007-07-21 drh: return strcmp(A->zLabel, B->zLabel); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Draw the header. dbda8d6ce9 2007-07-21 drh: */ 66f4caa379 2007-07-23 drh: void style_header(const char *zTitle){ dbda8d6ce9 2007-07-21 drh: const char *zLogInOut = "Logout"; 916b6e4b3b 2007-07-21 drh: login_check_credentials(); dbda8d6ce9 2007-07-21 drh: @ <html> 07eaead5dc 2007-09-23 jnc: @ <head> 07eaead5dc 2007-09-23 jnc: @ <title>%s(zTitle)</title> 07eaead5dc 2007-09-23 jnc: @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="%s(g.zBaseURL)/timeline.rss"> 5cd9597428 2007-09-24 jnc: @ <link rel="stylesheet" href="%s(g.zBaseURL)/style.css" type="text/css" media="screen"> 07eaead5dc 2007-09-23 jnc: @ </head> 5cd9597428 2007-09-24 jnc: @ <body> 5cd9597428 2007-09-24 jnc: @ <div id="page-title">%s(zTitle)</div> 5cd9597428 2007-09-24 jnc: @ <div id="login-status"> 9c952d247e 2007-07-31 drh: if( g.zLogin==0 ){ 5cd9597428 2007-09-24 jnc: @ not logged in dbda8d6ce9 2007-07-21 drh: zLogInOut = "Login"; dbda8d6ce9 2007-07-21 drh: }else{ 5cd9597428 2007-09-24 jnc: @ logged in as %h(g.zLogin) dbda8d6ce9 2007-07-21 drh: } 5cd9597428 2007-09-24 jnc: @ </div> 5cd9597428 2007-09-24 jnc: @ <div id="main-menu"> dbda8d6ce9 2007-07-21 drh: @ <a href="%s(g.zBaseURL)/index">Home</a> fd36718ad9 2007-07-31 drh: if( g.okRead ){ afcdc7ec97 2007-08-01 drh: @ | <a href="%s(g.zBaseURL)/leaves">Leaves</a> 5ebcedc33e 2007-07-31 dan: @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a> 5ebcedc33e 2007-07-31 dan: } 66f4caa379 2007-07-23 drh: if( g.okRdWiki ){ 66f4caa379 2007-07-23 drh: @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a> 66f4caa379 2007-07-23 drh: } 66f4caa379 2007-07-23 drh: #if 0 dbda8d6ce9 2007-07-21 drh: @ | <font color="#888888">Search</font> dbda8d6ce9 2007-07-21 drh: @ | <font color="#888888">Ticket</font> dbda8d6ce9 2007-07-21 drh: @ | <font color="#888888">Reports</font> 66f4caa379 2007-07-23 drh: #endif dbda8d6ce9 2007-07-21 drh: if( g.okSetup ){ dbda8d6ce9 2007-07-21 drh: @ | <a href="%s(g.zBaseURL)/setup">Setup</a> dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: if( !g.noPswd ){ dbda8d6ce9 2007-07-21 drh: @ | <a href="%s(g.zBaseURL)/login">%s(zLogInOut)</a> dbda8d6ce9 2007-07-21 drh: } 5cd9597428 2007-09-24 jnc: @ </div> dbda8d6ce9 2007-07-21 drh: if( nSubmenu>0 ){ 01ce2cf3dc 2007-09-24 jnc: @ <div id="sub-menu"> 5cd9597428 2007-09-24 jnc: int i; dbda8d6ce9 2007-07-21 drh: qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare); dbda8d6ce9 2007-07-21 drh: for(i=0; i<nSubmenu; i++){ dbda8d6ce9 2007-07-21 drh: struct Submenu *p = &aSubmenu[i]; dbda8d6ce9 2007-07-21 drh: char *zTail = i<nSubmenu-1 ? " | " : ""; dbda8d6ce9 2007-07-21 drh: if( p->zLink==0 ){ 5cd9597428 2007-09-24 jnc: @ <span class="label">%h(p->zLabel)</span> 5cd9597428 2007-09-24 jnc: @ <span class="tail">%s(zTail)</span> dbda8d6ce9 2007-07-21 drh: }else{ 5cd9597428 2007-09-24 jnc: @ <a class="label" href="%T(p->zLink)">%h(p->zLabel)</a> 5cd9597428 2007-09-24 jnc: @ <span class="tail">%s(zTail)</span> dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: } 01ce2cf3dc 2007-09-24 jnc: @ </div> dbda8d6ce9 2007-07-21 drh: } 5cd9597428 2007-09-24 jnc: @ <div id="page"> dbda8d6ce9 2007-07-21 drh: g.cgiPanic = 1; dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Draw the footer at the bottom of the page. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void style_footer(void){ 5cd9597428 2007-09-24 jnc: /* end the <div id="page"> from style_header() */ 5cd9597428 2007-09-24 jnc: @ </div> 5cd9597428 2007-09-24 jnc: @ <div id="style-footer"> c2d1e3c70a 2007-09-22 drh: @ Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE) 5cd9597428 2007-09-24 jnc: @ </div> dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** WEBPAGE: index dbda8d6ce9 2007-07-21 drh: ** WEBPAGE: home dbda8d6ce9 2007-07-21 drh: ** WEBPAGE: not_found dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void page_index(void){ 4f641e7e4e 2007-09-02 drh: char *zHome = db_get("homepage", 0); 4f641e7e4e 2007-09-02 drh: if( zHome ){ 4f641e7e4e 2007-09-02 drh: g.zExtra = zHome; 4f641e7e4e 2007-09-02 drh: g.okRdWiki = 1; 4f641e7e4e 2007-09-02 drh: wiki_page(); 4f641e7e4e 2007-09-02 drh: }else{ 4f641e7e4e 2007-09-02 drh: style_header("Main Title Page"); 4f641e7e4e 2007-09-02 drh: @ No homepage configured for this server 4f641e7e4e 2007-09-02 drh: style_footer(); 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: /* 5cd9597428 2007-09-24 jnc: ** TODO: COPIED FROM WIKI.C... BAD 5cd9597428 2007-09-24 jnc: */ 5cd9597428 2007-09-24 jnc: /* 5cd9597428 2007-09-24 jnc: ** Create a fake replicate of the "vfile" table as a TEMP table 5cd9597428 2007-09-24 jnc: ** using the manifest identified by manid. 5cd9597428 2007-09-24 jnc: */ 5cd9597428 2007-09-24 jnc: static void style_create_fake_vfile(int manid){ 5cd9597428 2007-09-24 jnc: static const char zVfileDef[] = 5cd9597428 2007-09-24 jnc: @ CREATE TEMP TABLE vfile( 5cd9597428 2007-09-24 jnc: @ id INTEGER PRIMARY KEY, -- ID of the checked out file 5cd9597428 2007-09-24 jnc: @ vid INTEGER REFERENCES blob, -- The version this file is part of. 5cd9597428 2007-09-24 jnc: @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 5cd9597428 2007-09-24 jnc: @ deleted BOOLEAN DEFAULT 0, -- True if deleted 5cd9597428 2007-09-24 jnc: @ rid INTEGER, -- Originally from this repository record 5cd9597428 2007-09-24 jnc: @ mrid INTEGER, -- Based on this record due to a merge 5cd9597428 2007-09-24 jnc: @ pathname TEXT, -- Full pathname 5cd9597428 2007-09-24 jnc: @ UNIQUE(pathname,vid) 5cd9597428 2007-09-24 jnc: @ ); 5cd9597428 2007-09-24 jnc: ; 5cd9597428 2007-09-24 jnc: db_multi_exec(zVfileDef); 5cd9597428 2007-09-24 jnc: load_vfile_from_rid(manid); 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: /* 5cd9597428 2007-09-24 jnc: ** WEBPAGE: style.css 5cd9597428 2007-09-24 jnc: */ 5cd9597428 2007-09-24 jnc: void page_style_css(void){ 5cd9597428 2007-09-24 jnc: Stmt q; 5cd9597428 2007-09-24 jnc: int id = 0; 5cd9597428 2007-09-24 jnc: int rid = 0; 5cd9597428 2007-09-24 jnc: int chnged = 0; 5cd9597428 2007-09-24 jnc: char *zPathname = 0; 5cd9597428 2007-09-24 jnc: char *z; 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: cgi_set_content_type("text/css"); 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: login_check_credentials(); 5cd9597428 2007-09-24 jnc: if( !g.localOpen ){ 5cd9597428 2007-09-24 jnc: int headid = db_int(0, 5cd9597428 2007-09-24 jnc: "SELECT cid FROM plink ORDER BY mtime DESC LIMIT 1" 5cd9597428 2007-09-24 jnc: ); 5cd9597428 2007-09-24 jnc: style_create_fake_vfile(headid); 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: db_prepare(&q, 5cd9597428 2007-09-24 jnc: "SELECT id, rid, chnged, pathname FROM vfile" 5cd9597428 2007-09-24 jnc: " WHERE (pathname='style.css' OR pathname LIKE '%%/style.css')" 5cd9597428 2007-09-24 jnc: " AND NOT deleted" 5cd9597428 2007-09-24 jnc: ); 5cd9597428 2007-09-24 jnc: if( db_step(&q)==SQLITE_ROW ){ 5cd9597428 2007-09-24 jnc: id = db_column_int(&q, 0); 5cd9597428 2007-09-24 jnc: rid = db_column_int(&q, 1); 5cd9597428 2007-09-24 jnc: chnged = db_column_int(&q, 2); 5cd9597428 2007-09-24 jnc: if( chnged || rid==0 ){ 5cd9597428 2007-09-24 jnc: zPathname = db_column_malloc(&q, 3); 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: db_finalize(&q); 5cd9597428 2007-09-24 jnc: if( id ){ 5cd9597428 2007-09-24 jnc: Blob src; 5cd9597428 2007-09-24 jnc: blob_zero(&src); 5cd9597428 2007-09-24 jnc: if( zPathname ){ 5cd9597428 2007-09-24 jnc: zPathname = mprintf("%s/%z", g.zLocalRoot, zPathname); 5cd9597428 2007-09-24 jnc: blob_read_from_file(&src, zPathname); 5cd9597428 2007-09-24 jnc: free(zPathname); 5cd9597428 2007-09-24 jnc: }else{ 5cd9597428 2007-09-24 jnc: content_get(rid, &src); 5cd9597428 2007-09-24 jnc: } 5cd9597428 2007-09-24 jnc: 5cd9597428 2007-09-24 jnc: z = blob_str(&src); 5cd9597428 2007-09-24 jnc: @ %s(z) 5cd9597428 2007-09-24 jnc: }else{ 5cd9597428 2007-09-24 jnc: /* No CSS file found, use our own */ 5cd9597428 2007-09-24 jnc: /* 5cd9597428 2007-09-24 jnc: ** Selector order: tags, ids, classes, other 5cd9597428 2007-09-24 jnc: ** Content order: margin, borders, padding, fonts, colors, other 5cd9597428 2007-09-24 jnc: ** Note: Once things are finialize a bit we can collapse this and 5cd9597428 2007-09-24 jnc: ** make it much smaller, if necessary. Right now, it's verbose 5cd9597428 2007-09-24 jnc: ** but easy to edit. 5cd9597428 2007-09-24 jnc: */ 5cd9597428 2007-09-24 jnc: @ body { 5cd9597428 2007-09-24 jnc: @ margin: 0px; 5cd9597428 2007-09-24 jnc: @ padding: 0px; 5cd9597428 2007-09-24 jnc: @ background-color: white; 5cd9597428 2007-09-24 jnc: @ } 5cd9597428 2007-09-24 jnc: @ #page-title { 5cd9597428 2007-09-24 jnc: @ padding: 10px 10px 10px 10px; 99eabf9b0c 2007-09-25 jnc: @ font-size: 1.8em; 5cd9597428 2007-09-24 jnc: @ font-weight: bold; 99eabf9b0c 2007-09-25 jnc: @ background-color: #6a7ec7; 99eabf9b0c 2007-09-25 jnc: @ color: #0a1e67; 5cd9597428 2007-09-24 jnc: @ } 5cd9597428 2007-09-24 jnc: @ #login-status { 5cd9597428 2007-09-24 jnc: @ padding: 0px 10px 10px 0px; 5cd9597428 2007-09-24 jnc: @ font-size: 0.9em; 5cd9597428 2007-09-24 jnc: @ text-align: right; 99eabf9b0c 2007-09-25 jnc: @ background-color: #6a7ec7; 99eabf9b0c 2007-09-25 jnc: @ color: white; 5cd9597428 2007-09-24 jnc: @ position: absolute; 5cd9597428 2007-09-24 jnc: @ top: 10; 5cd9597428 2007-09-24 jnc: @ right: 0; 5cd9597428 2007-09-24 jnc: @ } 5cd9597428 2007-09-24 jnc: @ #main-menu { 99eabf9b0c 2007-09-25 jnc: @ padding: 5px 10px 5px 10px; 5cd9597428 2007-09-24 jnc: @ font-size: 0.9em; 99eabf9b0c 2007-09-25 jnc: @ font-weight: bold; 5cd9597428 2007-09-24 jnc: @ text-align: center; 99eabf9b0c 2007-09-25 jnc: @ letter-spacing: 1px; 99eabf9b0c 2007-09-25 jnc: @ background-color: #414f84; 99eabf9b0c 2007-09-25 jnc: @ color: white; 5cd9597428 2007-09-24 jnc: @ } 5cd9597428 2007-09-24 jnc: @ #sub-menu { 5cd9597428 2007-09-24 jnc: @ padding: 3px 10px 3px 0px; 5cd9597428 2007-09-24 jnc: @ font-size: 0.9em; 5cd9597428 2007-09-24 jnc: @ text-align: center; 99eabf9b0c 2007-09-25 jnc: @ background-color: #414f84; 99eabf9b0c 2007-09-25 jnc: @ color: white; 99eabf9b0c 2007-09-25 jnc: @ } 99eabf9b0c 2007-09-25 jnc: @ #main-menu a, #main-menu a:visited, #sub-menu a, #sub-menu a:visited { 99eabf9b0c 2007-09-25 jnc: @ padding: 3px 10px 3px 10px; 99eabf9b0c 2007-09-25 jnc: @ color: white; 5cd9597428 2007-09-24 jnc: @ } 99eabf9b0c 2007-09-25 jnc: @ #main-menu a:hover, #sub-menu a:hover { 99eabf9b0c 2007-09-25 jnc: @ color: #414f84; 99eabf9b0c 2007-09-25 jnc: @ background-color: white; 5cd9597428 2007-09-24 jnc: @ } 5cd9597428 2007-09-24 jnc: @ #page { 5cd9597428 2007-09-24 jnc: @ padding: 10px 20px 10px 20px; 5cd9597428 2007-09-24 jnc: @ } 5cd9597428 2007-09-24 jnc: @ #style-footer { 5cd9597428 2007-09-24 jnc: @ font-size: 0.8em; 5cd9597428 2007-09-24 jnc: @ margin-top: 12px; 99eabf9b0c 2007-09-25 jnc: @ padding: 5px 10px 5px 10px; 99eabf9b0c 2007-09-25 jnc: @ text-align: right; 99eabf9b0c 2007-09-25 jnc: @ background-color: #414f84; 99eabf9b0c 2007-09-25 jnc: @ color: white; 5cd9597428 2007-09-24 jnc: @ } 4f641e7e4e 2007-09-02 drh: } dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** WEBPAGE: test_env dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void page_test_env(void){ 66f4caa379 2007-07-23 drh: style_header("Environment Test"); dbda8d6ce9 2007-07-21 drh: cgi_print_all(); dbda8d6ce9 2007-07-21 drh: style_footer(); dbda8d6ce9 2007-07-21 drh: }