From bab0433a274f4e22130793b5e77d3767492c4a9f Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Tue, 20 Dec 2011 05:21:12 -0500
Subject: [PATCH] First steps for Larry's address book

---
 skins/larry/images/listicons.png       |    0 
 program/steps/addressbook/edit.inc     |    9 
 skins/larry/templates/addressbook.html |   92 +++++++++
 skins/larry/templates/contactedit.html |   52 +++++
 skins/larry/styles.css                 |  108 +++++++++
 skins/larry/addressbook.css            |  182 ++++++++++++++++++
 skins/larry/images/buttons.png         |    0 
 skins/larry/templates/contact.html     |   33 +++
 skins/larry/mail.css                   |   22 +
 skins/larry/templates/compose.html     |    4 
 skins/larry/ui.js                      |   76 +++++++
 11 files changed, 552 insertions(+), 26 deletions(-)

diff --git a/program/steps/addressbook/edit.inc b/program/steps/addressbook/edit.inc
index 49915f5..eb6aa18 100644
--- a/program/steps/addressbook/edit.inc
+++ b/program/steps/addressbook/edit.inc
@@ -176,9 +176,8 @@
 {
   global $OUTPUT;
 
-  // add ID if not given
-  if (!$attrib['id'])
-    $attrib['id'] = 'rcmUploadbox';
+  // set defaults
+  $attrib += array('id' => 'rcmUploadbox', 'buttons' => 'yes');
 
   // find max filesize value
   $max_filesize = parse_bytes(ini_get('upload_max_filesize'));
@@ -196,10 +195,10 @@
       $hidden->show() .
       html::div(null, $input->show()) .
       html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
-      html::div('buttons',
+      (get_boolean($attrib['buttons']) ? html::div('buttons',
         $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' .
         $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('upload-photo', this.form)"))
-      )
+      ) : '')
     )
   );
 
diff --git a/skins/larry/addressbook.css b/skins/larry/addressbook.css
index 819a432..57a1b0d 100644
--- a/skins/larry/addressbook.css
+++ b/skins/larry/addressbook.css
@@ -10,4 +10,184 @@
  * See http://creativecommons.org/licenses/by-sa/3.0/ for details.
  *
  * $Id$
- */
\ No newline at end of file
+ */
+
+#addressview-left {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 220px;
+	bottom: 0;
+}
+
+#addressview-right {
+	position: absolute;
+	top: 0;
+	left: 232px;
+	right: 0;
+	bottom: 0;
+}
+
+#addressbooktoolbar {
+	position: absolute;
+	top: -6px;
+	left: 0;
+	right: 0;
+	height: 40px;
+	white-space: nowrap;
+}
+
+#directorylistbox {
+	position: absolute;
+	top: 42px;
+	left: 0;
+	width: 100%;
+	bottom: 0;
+}
+
+#addresslist {
+	position: absolute;
+	top: 42px;
+	left: 0;
+	width: 280px;
+	bottom: 0;
+}
+
+#contacts-box {
+	position: absolute;
+	top: 42px;
+	left: 292px;
+	right: 0;
+	bottom: 0;
+}
+
+#addressview-left #quicksearchbar input {
+	width: 156px;
+}
+
+#directorylist li a,
+#contacts-table .contact td.name {
+	background: url(images/listicons.png) -100px 0 no-repeat;
+	overflow: hidden;
+	padding-left: 36px;
+	text-overflow: ellipsis;
+}
+
+#directorylist li.addressbook a {
+	background-position: 6px -766px;
+}
+
+#directorylist li.addressbook.selected a {
+	background-position: 6px -791px;
+}
+
+#directorylist li.contactgroup a {
+	padding-left: 62px;
+	background-position: 32px -1555px;
+}
+
+#directorylist li.contactgroup.selected a {
+	background-position: 32px -1579px;
+}
+
+#contacts-table .contact td.name {
+	background-position: 6px -1603px;
+}
+
+#contacts-table .contact.selected td.name,
+#contacts-table .contact.unfocused td.name {
+	background-position: 6px -1627px;
+	font-weight: bold;
+}
+
+#contact-frame {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 28px;
+	border: 0;
+}
+
+#headerbuttons {
+	position: absolute;
+	top: 48px;
+	right: 10px;
+	width: auto;
+	z-index: 10;
+}
+
+#sourcename {
+	color: #999;
+	font-size: 10px;
+	margin: -5px 0 8px 2px;
+}
+
+#contactphoto {
+	float: left;
+	margin: 0 18px 20px 0;
+	width: 112px;
+}
+
+#contactpic {
+	width: 112px;
+	min-height: 112px;
+	background: white;
+}
+
+#contactpic img {
+	width: 112px;
+}
+
+#contacthead {
+	border: 0;
+	margin: 0 20em 1em 0;
+	padding: 0;
+	line-height: 1.5em;
+	font-size: 12px;
+}
+
+#contacthead .names span.namefield,
+#contacthead .names input {
+	font-size: 140%;
+	font-weight: bold;
+}
+
+#contacthead .displayname span.namefield {
+	font-size: 120%;
+	font-weight: bold;
+}
+
+#contacthead span.nickname:before,
+#contacthead span.nickname:after,
+#contacthead input.ff_nickname:before,
+#contacthead input.ff_nickname:after {
+	content: '"';
+}
+
+#contacthead input {
+	margin-right: 6px;
+	margin-bottom: 0.2em;
+}
+
+#contacthead .names input,
+#contacthead .addnames input {
+	width: 180px;
+}
+
+#contacthead input.ff_prefix,
+#contacthead input.ff_suffix {
+	width: 90px;
+}
+
+a.deletebutton {
+	position: relative;
+	left: 5px;
+	top: -3px;
+	display: inline-block;
+	width: 24px;
+	height: 18px;
+	text-decoration: none;
+	text-indent: -1000px;
+	background: url(images/buttons.png) -7px -337px no-repeat;
+}
diff --git a/skins/larry/images/buttons.png b/skins/larry/images/buttons.png
index 84207cc..438768f 100644
--- a/skins/larry/images/buttons.png
+++ b/skins/larry/images/buttons.png
Binary files differ
diff --git a/skins/larry/images/listicons.png b/skins/larry/images/listicons.png
index 0fb0bdc..5f4473f 100644
--- a/skins/larry/images/listicons.png
+++ b/skins/larry/images/listicons.png
Binary files differ
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index 8a29fa7..44721c5 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -541,14 +541,16 @@
 	background-position: -24px -1036px;
 }
 
-#messagelist tr td.flag span.unflagged:hover {
+#messagelist tr td.flag span.unflagged:hover,
+#messagelist tr td.status span.msgicon:hover {
 	background-position: 0 -1056px;
 }
 
 #messagelist tr td.subject span.msgicon,
 #messagelist tr td.subject span.unreadchildren {
 	background-position: 0 -1056px;
-	margin: 0 4px 0 0;
+	margin: 0 1px 0 0;
+	width: 24px;
 }
 
 #messagelist tr td.subject span.replied {
@@ -580,8 +582,13 @@
 */
 #messagelist tr td.status span.status,
 #messagelist tr td.status span.unread,
-#messagelist tr td.subject span.unread {
+#messagelist tr td.subject span.unread,
+#messagelist tr td.status span.unread:hover {
 	background-position: 0 -1016px;
+}
+
+#messagelist thead tr td.status span.status {
+	background-position: -24px -1016px;
 }
 
 #messagelist tr td div.collapsed {
@@ -1132,10 +1139,11 @@
 #compose-attachments {
 	position: absolute;
 	right: 0;
-	top: 0;
+	top: 1px;
 	bottom: 0;
 	width: 240px;
 	background: #f0f0f0;
+	border-left: 1px solid #ddd;
 	padding: 8px;
 	overflow: auto;
 }
@@ -1171,3 +1179,9 @@
 	border: 0 !important;
 }
 
+#composebody_toolbargroup {
+	border-bottom: 1px solid #ddd;
+}
+
+
+
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index 80943a6..48c8c6f 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -35,6 +35,7 @@
 input[type="text"],
 input[type="password"],
 textarea {
+	margin: 0; /* Safari by default adds a margin */
 	padding: 4px;
 	border: 1px solid #b2b2b2;
 	border-radius: 4px;
@@ -82,6 +83,7 @@
 	-webkit-box-shadow: 0 1px 1px 0 #ccc;
 	-moz-box-shadow: 0 1px 1px 0 #ccc;
 	text-decoration: none;
+	outline: none;
 }
 
 .formbuttons input.button {
@@ -103,7 +105,8 @@
 	-moz-box-shadow: 0 1px 1px 0 #ccc, inset 0 1px 0 0 #888;
 }
 
-.formbuttons input.button:hover {
+.formbuttons input.button:hover,
+.formbuttons input.button:focus {
 	color: #f2f2f2;
 	border-color: #465864;
 	box-shadow: 0 0 5px 2px rgba(71,135,177, 0.6), inset 0 1px 0 0 #888;
@@ -176,7 +179,8 @@
 }
 
 a.button:hover,
-input.button:hover {
+input.button:hover,
+input.button:focus {
 	border-color: #4fadd5;
 	box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6);
 	-moz-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6);
@@ -342,6 +346,11 @@
 a.iconlink.edit {
 	background-position: -7px -397px;
 }
+
+a.iconlink.delete {
+	background-position: -7px -337px;
+}
+
 
 /*** message bar ***/
 
@@ -698,6 +707,10 @@
 	margin-top: 1px;
 }
 
+.boxfooter .listbutton.disabled {
+	opacity: 0.4;
+}
+
 .boxfooter .listbutton .inner {
 	display: inline-block;
 	width: 48px;
@@ -707,7 +720,11 @@
 }
 
 .boxfooter .listbutton.add .inner {
-	background-position: 10px -1210px;
+	background-position: 10px -1211px;
+}
+
+.boxfooter .listbutton.delete .inner {
+	background-position: 10px -1252px;
 }
 
 .boxfooter .listbutton.groupactions .inner {
@@ -758,6 +775,7 @@
 	top: 0;
 	left: 0;
 	width: 100%;
+	z-index: 100;
 }
 
 .boxcontent {
@@ -892,11 +910,12 @@
 	-o-box-shadow: inset 0 1px 0 0 #fff;
 }
 
-#login-form input.button:hover {
-	box-shadow: 0 0 5px 2px rgba(71,135,177, 0.6), inset 0 1px 0 0 #fff;
-	-moz-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.6), inset 0 1px 0 0 #fff;
-	-webkit-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.6), inset 0 1px 0 0 #fff;
-	-o-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.6), inset 0 1px 0 0 #fff;
+#login-form input.button:hover,
+#login-form input.button:focus {
+	box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9), inset 0 1px 0 0 #fff;
+	-moz-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9), inset 0 1px 0 0 #fff;
+	-webkit-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9), inset 0 1px 0 0 #fff;
+	-o-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9), inset 0 1px 0 0 #fff;
 }
 
 #login-form input.button:active {
@@ -982,7 +1001,7 @@
 	overflow: hidden;
 	text-overflow: ellipsis;
 	white-space: nowrap;
-	padding: 28px 2px 2px 2px;
+	padding: 28px 2px 0 2px;
 	text-shadow: 0px 1px 1px #eee;
 	box-shadow: none;
 	-moz-box-shadow: none;
@@ -1067,6 +1086,18 @@
 
 .toolbar a.button.spellcheck {
 	background-position: center -930px;
+}
+
+.toolbar a.button.search {
+	background-position: center -970px;
+}
+
+.toolbar a.button.import {
+	background-position: center -1010px;
+}
+
+.toolbar a.button.export {
+	background-position: center -1050px;
 }
 
 
@@ -1228,6 +1259,11 @@
 	margin: 20px 0 4px 0;
 }
 
+.ui-dialog .prompt input {
+	display: block;
+	margin: 8px 0;
+}
+
 .hint {
 	margin: 4px 0;
 	color: #999;
@@ -1300,3 +1336,57 @@
 	background: url(images/buttons.png) -8px -360px no-repeat;
 }
 
+
+/*** fieldset tabs ***/
+
+.tabsbar {
+	margin-bottom: 10px;
+	padding-top: 15px;
+	height: 27px;
+}
+
+.tabsbar .tablink {
+	padding: 15px 1px 15px 0;
+	background: #f8f8f8;
+	background: -moz-linear-gradient(top, #f8f8f8 0%, #d3d3d3 50%, #f8f8f8 100%);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(50%,#d3d3d3), color-stop(100%,#f8f8f8));
+	background: -webkit-linear-gradient(top, #f8f8f8 0%, #d3d3d3 50%, #f8f8f8 100%);
+	background: -o-linear-gradient(top, #f8f8f8 0%, #d3d3d3 50%, #f8f8f8 100%);
+	background: -ms-linear-gradient(top, #f8f8f8 0%, #d3d3d3 50%, #f8f8f8 100%);
+	background: linear-gradient(top, #f8f8f8 0%, #d3d3d3 50%, #f8f8f8 100%);
+}
+
+.tabsbar .tablink:last-child {
+	background: none;
+}
+
+.tabsbar .tablink:last-child a {
+	border-right: 0;
+}
+
+.tabsbar .tablink a {
+	padding: 15px;
+	color: #999;
+	font-size: 12px;
+	font-weight: bold;
+	text-decoration: none;
+	background: #fff;
+	border-right: 1px solid #fafafa;
+}
+
+.tabsbar .tablink.selected a {
+	color: #004458;
+	background: #fff;
+	background: -moz-linear-gradient(top, #fff 40%, #efefef 100%);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(40%,#fff), color-stop(100%,#efefef));
+	background: -o-linear-gradient(top, #fff 40%, #efefef 100%);
+	background: -ms-linear-gradient(top, #fff 40%, #efefef 100%);
+	background: linear-gradient(top, #fff 40%, #efefef 100%);
+}
+
+fieldset.tab {
+	border: 0;
+	padding: 0;
+}
+
+
diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html
new file mode 100644
index 0000000..23da141
--- /dev/null
+++ b/skins/larry/templates/addressbook.html
@@ -0,0 +1,92 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+</head>
+<body>
+
+<roundcube:include file="/includes/header.html" />
+
+<div id="mainscreen">
+
+<div id="addressview-left">
+
+<!-- search box -->
+<div id="quicksearchbar">
+<roundcube:object name="searchform" id="quicksearchbox" />
+<roundcube:button name="searchmenulink" id="searchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('searchmenu');return false" title="searchmod" content=" " />
+<roundcube:button command="reset-search" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
+</div>
+
+<!-- sources/groups list -->
+<div id="directorylistbox" class="uibox listbox">
+<h2 class="boxtitle"><roundcube:label name="groups" /></h2>
+<div class="scroller withfooter">
+	<roundcube:object name="directorylist" id="directorylist" class="listing" />
+</div>
+<div class="boxfooter">
+	<roundcube:button command="group-create" type="link" title="newcontactgroup" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button name="groupoptions" id="groupoptionslink" type="link" title="moreactions" class="listbutton groupactions" onclick="UI.show_popup('groupoptions');return false" innerClass="inner" content="&#9881;" />
+</div>
+</div>
+
+</div><!-- end addressview-left -->
+
+<div id="addressview-right">
+
+<!-- toolbar -->
+<div id="addressbooktoolbar" class="toolbar">
+	<roundcube:button command="advanced-search" type="link" class="button search disabled" classAct="button search" classSel="button search pressed" label="advsearch" />
+	<roundcube:button command="compose" type="link" class="button compose disabled" classAct="button compose" classSel="button compose pressed" label="writenewmessage" />
+	<roundcube:button command="import" type="link" class="button import disabled" classAct="button import" classSel="button import pressed" label="importcontacts" />
+	<roundcube:button command="export" type="link" class="button export disabled" classAct="button export" classSel="button export pressed" label="exportvcards" />
+	<roundcube:container name="toolbar" id="addressbooktoolbar" />
+</div>
+
+<!-- contacts list -->
+<div id="addresslist" class="uibox listbox">
+<h2 class="boxtitle"><roundcube:label name="contacts" /></h2>
+<div class="scroller withfooter">
+<roundcube:object name="addresslist" id="contacts-table" class="listing" noheader="true" />
+</div>
+<div class="boxfooter">
+	<roundcube:button command="add" type="link" title="newcontact" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button command="delete" type="link" title="deletecontact" class="listbutton delete disabled" classAct="listbutton delete" innerClass="inner" content="x" />
+</div>
+</div>
+
+
+<div id="contacts-box" class="uibox">
+	<roundcube:object name="addressframe" id="contact-frame" style="width:100%; height:96%" src="/watermark.html" />
+	<roundcube:object name="message" id="message" class="statusbar" />
+</div>
+
+
+</div><!-- end addressview-right -->
+
+</div><!-- end mainscreen -->
+
+
+<div id="searchmenu" class="popupmenu">
+	<ul class="toolbarmenu">
+		<li><label><input type="checkbox" name="s_mods[]" value="name" onclick="UI.set_searchmod(this)" /> <roundcube:label name="name" /></label></li>
+		<li><label><input type="checkbox" name="s_mods[]" value="firstname" onclick="UI.set_searchmod(this)" /> <roundcube:label name="firstname" /></label></li>
+		<li><label><input type="checkbox" name="s_mods[]" value="surname" onclick="UI.set_searchmod(this)" /> <roundcube:label name="surname" /></label></li>
+		<li><label><input type="checkbox" name="s_mods[]" value="email" onclick="UI.set_searchmod(this)" /> <roundcube:label name="email" /></label></li>
+		<li><label><input type="checkbox" name="s_mods[]" value="*" onclick="UI.set_searchmod(this)" /> <roundcube:label name="allfields" /></label></li>
+	</ul>
+</div>
+
+<div id="groupoptions" class="popupmenu">
+	<ul id="groupoptionsmenu" class="toolbarmenu">
+		<li><roundcube:button command="group-rename" label="grouprename" classAct="active" /></li>
+		<li><roundcube:button command="group-delete" label="groupdelete" classAct="active" /></li>
+		<li><roundcube:button command="search-create" label="searchsave" classAct="active" /></li>
+		<li><roundcube:button command="search-delete" label="searchdelete" classAct="active" /></li>
+		<roundcube:container name="groupoptions" id="groupoptionsmenu" />
+	</ul>
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html>
diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html
index b59c963..aad516d 100644
--- a/skins/larry/templates/compose.html
+++ b/skins/larry/templates/compose.html
@@ -104,8 +104,8 @@
 <!-- (collapsable) message options -->
 <div id="composeoptionsbox">
 	<span class="composeoption">
-		<label><roundcube:label name="options" /></label>
-		<a href="#options" id="composeoptionstoggle">&nbsp;</a>
+		<label><roundcube:label name="options" />
+			<a href="#options" id="composeoptionstoggle">&nbsp;</a></label>
 	</span>
 	
 	<div id="composeoptions">
diff --git a/skins/larry/templates/contact.html b/skins/larry/templates/contact.html
new file mode 100644
index 0000000..d252049
--- /dev/null
+++ b/skins/larry/templates/contact.html
@@ -0,0 +1,33 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+</head>
+<body class="iframe">
+
+<h1 class="boxtitle"><roundcube:label name="contactproperties" /></h1>
+
+<div id="contact-details" class="boxcontent">
+	<roundcube:if condition="strlen(env:sourcename)" />
+		<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
+	<roundcube:endif />
+
+	<div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /></div>
+	<roundcube:object name="contacthead" id="contacthead" />
+	<br style="clear:both" />
+
+	<div id="contacttabs" class="tabbed">
+		<roundcube:object name="contactdetails" />
+	</div>
+
+</div>
+
+<div id="headerbuttons" class="formbuttons">
+	<roundcube:button command="edit" type="input" class="button mainaction" label="editcontact" condition="!ENV:readonly" />
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html>
diff --git a/skins/larry/templates/contactedit.html b/skins/larry/templates/contactedit.html
new file mode 100644
index 0000000..562e6d2
--- /dev/null
+++ b/skins/larry/templates/contactedit.html
@@ -0,0 +1,52 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+</head>
+<body class="iframe">
+
+<h1 class="boxtitle">
+	<roundcube:if condition="env:action=='add'" /><roundcube:label name="addcontact" />
+	<roundcube:else /><roundcube:label name="editcontact" />
+<roundcube:endif /></h1>
+
+<form name="editform" method="post" action="./" id="contact-details" class="boxcontent">
+	<roundcube:if condition="strlen(env:sourcename)" />
+		<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" condition="env:action!='add'" /><roundcube:object name="sourceselector" id="sourceselect" condition="env:action=='add'" /></div>
+	<roundcube:endif />
+
+	<div id="contactphoto">
+		<roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" />
+		<div class="formlinks">
+			<roundcube:button command="upload-photo" id="uploadformlink" type="link" label="replacephoto" class="iconlink upload disabled" classAct="iconlink upload active" onclick="UI.show_uploadform();return false" condition="env:photocol" /><br/>
+			<roundcube:button command="delete-photo" type="link" label="delete" class="iconlink delete disabled" classAct="iconlink delete active" condition="env:photocol" />
+		</div>
+	</div>
+	<roundcube:object name="contactedithead" id="contacthead" size="16" form="editform" />
+	<br style="clear:both" />
+
+	<div id="contacttabs" class="tabbed">
+		<roundcube:object name="contacteditform" size="40" textareacols="60" form="editform" />
+	</div>
+
+</form>
+
+<div id="headerbuttons" class="formbuttons">
+	<roundcube:button command="save" type="input" class="button mainaction" label="save" />
+	<roundcube:button command="show" type="input" class="button" label="cancel" condition="env:action=='edit'" />
+	<roundcube:button name="cancel" type="input" class="button" label="cancel" onclick="history.back()" condition="env:action=='add'" />
+</div>
+
+<div id="upload-dialog" class="propform popupdialog">
+	<roundcube:object name="photoUploadForm" id="upload-form" size="30" buttons="no" />
+	<div class="formbuttons">
+		<roundcube:button command="upload-photo" type="input" class="button mainaction" label="upload" />
+		<roundcube:button name="close" type="input" class="button" label="cancel" onclick="UI.show_uploadform()" />
+	</div>
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html>
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 806ff2c..4b811cb 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -34,6 +34,7 @@
 
   // export public methods
   this.init = init;
+  this.init_tabs = init_tabs;
   this.show_popup = show_popup;
   this.set_searchmod = set_searchmod;
   this.show_uploadform = show_uploadform;
@@ -68,12 +69,12 @@
       else if (rcmail.env.action == 'compose') {
         layout_composeview();
 
-        $('#composeoptionstoggle').click(function(){
-          $(this).toggleClass('enabled');
+        $('#composeoptionstoggle').parent().click(function(){
+          $('#composeoptionstoggle').toggleClass('enabled');
           $('#composeoptions').toggle();
           layout_composeview();
           return false;
-        });
+        }).css('cursor', 'pointer');
 
         new rcube_splitter({ id:'composesplitterv', p1:'#composeview-left', p2:'#composeview-right',
           orientation:'v', relative:true, start:248, min:150, size:12 }).init();
@@ -107,6 +108,12 @@
           orientation:'v', relative:true, start:305, min:150, size:12 }).init();
       }
     }
+    else if (rcmail.env.task == 'addressbook') {
+
+    }
+
+    // turn a group of fieldsets into tabs
+    $('.tabbed').each(function(idx, elem){ init_tabs(elem); })
 
     $(document.body).bind('mouseup', function(e){
       var config, obj, target = e.target;
@@ -189,8 +196,8 @@
     body.width(w).height(h);
 
     if (window.tinyMCE && tinyMCE.get('composebody')) {
-      $('#composebody_tbl').width((w+11)+'px').height('').css('margin-top', '1px');
-      $('#composebody_ifr').width((w+11)+'px').height((h-24)+'px');
+      $('#composebody_tbl').width((w+12)+'px').height('').css('margin-top', '1px');
+      $('#composebody_ifr').width((w+12)+'px').height((h-22)+'px');
     }
     else {
       $('#googie_edit_layer').height(h+'px');
@@ -540,6 +547,65 @@
     $('#' + which + '-link').show();
     this.resize_compose_body();
   }
+
+
+  /**
+   * Fieldsets-to-tabs converter
+   */
+  function init_tabs(elem, current)
+  {
+    var id = elem.id,
+      content = $(elem),
+      fs = content.children('fieldset');
+
+    if (!fs.length)
+      return;
+
+    if (!id) {
+      id = 'rcmtabcontainer';
+      elem.attr('id', id);
+    }
+
+    // first hide not selected tabs
+    current = current || 0;
+    fs.each(function(idx) { if (idx != current) $(this).hide(); });
+
+    // create tabs container
+    var tabs = $('<div>').addClass('tabsbar').prependTo(content);
+
+    // convert fildsets into tabs
+    fs.each(function(idx) {
+      var tab, a, elm = $(this), legend = elm.children('legend');
+
+      // create a tab
+      a   = $('<a>').text(legend.text()).attr('href', '#');
+      tab = $('<span>').attr({'id': 'tab'+idx, 'class': 'tablink'})
+        .click(function() { show_tab(id, idx); return false })
+
+      // remove legend
+      legend.remove();
+      // style fieldset
+      elm.addClass('tab');
+      // style selected tab
+      if (idx == current)
+        tab.addClass('selected');
+
+      // add the tab to container
+      tab.append(a).appendTo(tabs);
+    });
+  }
+
+  function show_tab(id, index)
+  {
+    var fs = $('#'+id).children('fieldset');
+
+    fs.each(function(idx) {
+      // Show/hide fieldset (tab content)
+      $(this)[index==idx ? 'show' : 'hide']();
+      // Select/unselect tab
+      $('#tab'+idx).toggleClass('selected', idx==index);
+    });
+  }
 }
 
 

--
Gitblit v1.9.1