From e189a6ca18fe43def249c78a0e89405012981de5 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 30 Jun 2008 05:36:18 -0400
Subject: [PATCH] - Added flag column on messages list (#1484623)

---
 CHANGELOG                             |    4 +
 skins/default/templates/mail.html     |    6 +
 program/include/rcube_imap.php        |    2 
 skins/default/mail.css                |    3 
 program/steps/mail/func.inc           |   26 +++++++-
 program/localization/en_US/labels.inc |    2 
 program/lib/imap.inc                  |    3 +
 program/localization/pl_PL/labels.inc |    2 
 program/steps/mail/mark.inc           |    4 +
 program/js/app.js                     |  103 +++++++++++++++++++++++++++++++---
 10 files changed, 137 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 9bde8fb..3e08284 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,10 @@
 CHANGELOG RoundCube Webmail
 ---------------------------
 
+2008/06/30 (alec)
+----------
+- Added flag column on messages list (#1484623)
+
 2008/06/24 (alec)
 ----------
 - Patched Mail/MimePart.php (http://pear.php.net/bugs/bug.php?id=14232)
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 858a1e2..395a1b3 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -1315,6 +1315,8 @@
       $result = iil_C_Undelete($this->conn, $this->mailbox, join(',', array_values($msg_ids)));
     else if ($flag=='UNSEEN')
       $result = iil_C_Unseen($this->conn, $this->mailbox, join(',', array_values($msg_ids)));
+    else if ($flag=='UNFLAGGED')
+      $result = iil_C_UnFlag($this->conn, $this->mailbox, join(',', array_values($msg_ids)), 'FLAGGED');
     else
       $result = iil_C_Flag($this->conn, $this->mailbox, join(',', array_values($msg_ids)), $flag);
 
diff --git a/program/js/app.js b/program/js/app.js
index 74e0274..657a45d 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -136,7 +136,7 @@
           this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; });
 
           this.message_list.init();
-          this.enable_command('toggle_status', true);
+          this.enable_command('toggle_status', 'toggle_flag', true);
           
           if (this.gui_objects.mailcontframe)
             {
@@ -373,6 +373,7 @@
       row.deleted = this.env.messages[uid].deleted ? true : false;
       row.unread = this.env.messages[uid].unread ? true : false;
       row.replied = this.env.messages[uid].replied ? true : false;
+      row.flagged = this.env.messages[uid].flagged ? true : false;
       }
 
     // set eventhandler to message icon
@@ -382,6 +383,24 @@
       row.icon.id = 'msgicn_'+row.uid;
       row.icon._row = row.obj;
       row.icon.onmousedown = function(e) { p.command('toggle_status', this); };
+      }
+
+    // global variable 'flagged_col' may be not defined yet
+    if (!this.env.flagged_col && this.env.coltypes)
+      {
+      var found;
+      if((found = find_in_array('flag', this.env.coltypes)) >= 0)
+          this.set_env('flagged_col', found+1);
+      }
+
+    // set eventhandler to flag icon, if icon found
+    if (this.env.flagged_col && (row.flagged_icon = row.obj.cells[this.env.flagged_col].childNodes[0]) 
+	&& row.flagged_icon.nodeName=='IMG')
+      {
+      var p = this;
+      row.flagged_icon.id = 'flaggedicn_'+row.uid;
+      row.flagged_icon._row = row.obj;
+      row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); };
       }
   };
 
@@ -708,6 +727,24 @@
         this.mark_message(flag, uid);
         break;
         
+      case 'toggle_flag':
+        if (props && !props._row)
+          break;
+
+        var uid;
+        var flag = 'flagged';
+
+        if (props._row.uid)
+          {
+          uid = props._row.uid;
+          this.message_list.dont_select = true;
+          // toggle flagged/unflagged
+          if (this.message_list.rows[uid].flagged)
+            flag = 'unflagged';
+          }
+        this.mark_message(flag, uid);
+        break;
+
       case 'always-load':
         if (this.env.uid && this.env.sender) {
           this.add_contact(urlencode(this.env.sender));
@@ -1526,7 +1563,7 @@
       {
       for (var n=0; n<selection.length; n++)
         {
-    	  a_uids[a_uids.length] = selection[n];
+          a_uids[a_uids.length] = selection[n];
         }
       }
 
@@ -1538,8 +1575,10 @@
         id = a_uids[n];
         if ((flag=='read' && this.message_list.rows[id].unread) 
 	    || (flag=='unread' && !this.message_list.rows[id].unread)
-            || (flag=='delete' && !this.message_list.rows[id].deleted)
-	    || (flag=='undelete' && this.message_list.rows[id].deleted))
+        || (flag=='delete' && !this.message_list.rows[id].deleted)
+	    || (flag=='undelete' && this.message_list.rows[id].deleted)
+	    || (flag=='flagged' && !this.message_list.rows[id].flagged)
+	    || (flag=='unflagged' && this.message_list.rows[id].flagged))
 	  {
 	    r_uids[r_uids.length] = id;
 	  }
@@ -1558,6 +1597,10 @@
         case 'delete':
         case 'undelete':
           this.toggle_delete_status(r_uids);
+          break;
+        case 'flagged':
+        case 'unflagged':
+          this.toggle_flagged_status(flag, a_uids);
           break;
       }
     };
@@ -1625,6 +1668,32 @@
       }
   }
   
+  
+  // set image to flagged or unflagged
+  this.toggle_flagged_status = function(flag, a_uids)
+  {
+    // mark all message rows as flagged/unflagged
+    var icn_src;
+    var rows = this.message_list.rows;
+    for (var i=0; i<a_uids.length; i++)
+      {
+      uid = a_uids[i];
+      if (rows[uid])
+        {
+        rows[uid].flagged = (flag=='flagged' ? true : false);
+
+        if (rows[uid].flagged && this.env.flaggedicon)
+          icn_src = this.env.flaggedicon;
+        else if (this.env.unflaggedicon)
+          icn_src = this.env.unflaggedicon;
+
+        if (rows[uid].flagged_icon && icn_src)
+          rows[uid].flagged_icon.src = icn_src;
+        }
+      }
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
+  };
   
   // mark all message rows as deleted/undeleted
   this.toggle_delete_status = function(a_uids)
@@ -3243,9 +3312,12 @@
 
         cell.id = 'rcmHead'+col;
         }
-        
-      if (col == 'subject' && this.message_list)
+      else if (col == 'subject' && this.message_list)
         this.message_list.subject_col = n+1;
+      else if (col == 'flag' && this.env.unflaggedicon)
+        {
+	  cell.innerHTML = '<img src="'+this.env.unflaggedicon+'" alt="" />';
+	}
       }
   };
 
@@ -3261,7 +3333,8 @@
     
     this.env.messages[uid] = {deleted:flags.deleted?1:0,
                               replied:flags.replied?1:0,
-                              unread:flags.unread?1:0};
+                              unread:flags.unread?1:0,
+                              flagged:flags.flagged?1:0};
     
     var row = document.createElement('TR');
     row.id = 'rcmrow'+uid;
@@ -3276,7 +3349,7 @@
 
     var col = document.createElement('TD');
     col.className = 'icon';
-    col.innerHTML = icon ? '<img src="'+icon+'" alt="" border="0" />' : '';
+    col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : '';
     row.appendChild(col);
 
     // add each submitted col
@@ -3285,13 +3358,23 @@
       var c = this.coltypes[n];
       col = document.createElement('TD');
       col.className = String(c).toLowerCase();
-      col.innerHTML = cols[c];
+      
+      if (c=='flag')
+        {
+        if (flags.flagged && this.env.flaggedicon)
+          col.innerHTML = '<img src="'+this.env.flaggedicon+'" alt="" />';
+        else if(this.env.unflaggedicon)
+          col.innerHTML = '<img src="'+this.env.unflaggedicon+'" alt="" />';
+	}
+      else
+        col.innerHTML = cols[c];
+
       row.appendChild(col);
       }
 
     col = document.createElement('TD');
     col.className = 'icon';
-    col.innerHTML = attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" border="0" />' : '';
+    col.innerHTML = attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" />' : '';
     row.appendChild(col);
 
     this.message_list.insert_row(row, attop);
diff --git a/program/lib/imap.inc b/program/lib/imap.inc
index ce02071..e3df356 100644
--- a/program/lib/imap.inc
+++ b/program/lib/imap.inc
@@ -149,6 +149,7 @@
 	var $answered = false;
 	var $forwarded = false;
 	var $junk = false;
+	var $flagged = false;
 }
 
 /**
@@ -1758,6 +1759,8 @@
 							    $result[$id]->forwarded = true;
 							} else if (strcasecmp($val, '$MDNSent') == 0) {
 							    $result[$id]->mdn_sent = true;
+							} else if (strcasecmp($val, 'Flagged') == 0) {
+							     $result[$id]->flagged = true;
 							}
 						}
 						$result[$id]->flags = $flags_a;
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index cf7c54c..2c5ea56 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -141,6 +141,8 @@
 $labels['markmessages']     = 'Mark messages';
 $labels['markread']         = 'As read';
 $labels['markunread']       = 'As unread';
+$labels['markflagged']         = 'As flagged';
+$labels['markunflagged']       = 'As unflagged';
 
 $labels['select'] = 'Select';
 $labels['all'] = 'All';
diff --git a/program/localization/pl_PL/labels.inc b/program/localization/pl_PL/labels.inc
index d619b65..02b6780 100644
--- a/program/localization/pl_PL/labels.inc
+++ b/program/localization/pl_PL/labels.inc
@@ -123,6 +123,8 @@
 $labels['markmessages'] = 'Oznacz wiadomość';
 $labels['markread'] = 'Jako przeczytaną';
 $labels['markunread'] = 'Jako nieprzeczytaną';
+$labels['markflagged'] = 'Jako oflagowaną';
+$labels['markunflagged'] = 'Jako nieoflagowaną';
 $labels['select'] = 'Zaznacz';
 $labels['all'] = 'Wszystkie';
 $labels['none'] = 'Anuluj';
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 7fbda27..02419be 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -74,7 +74,6 @@
   $OUTPUT->set_pagetitle(rcmail_localize_foldername($IMAP->get_mailbox_name()));
 
 
-
 /**
  * return the message list as HTML table
  */
@@ -83,7 +82,7 @@
   global $IMAP, $CONFIG, $COMM_PATH, $OUTPUT;
 
   $skin_path = $CONFIG['skin_path'];
-  $image_tag = '<img src="%s%s" alt="%s" border="0" />';
+  $image_tag = '<img src="%s%s" alt="%s" />';
 
   // check to see if we have some settings for sorting
   $sort_col   = $_SESSION['sort_col'];
@@ -103,7 +102,6 @@
   $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
 
   $out = '<table' . $attrib_str . ">\n";
-
 
   // define list of cols to be displayed
   $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
@@ -133,7 +131,7 @@
   foreach ($a_show_cols as $col)
     {
     // get column name
-    $col_name = Q(rcube_label($col));
+    $col_name = $col != 'flag' ? Q(rcube_label($col)) : sprintf($image_tag, $skin_path, $attrib['unflaggedicon'], '');
 
     // make sort links
     $sort = '';
@@ -197,7 +195,7 @@
   // create row for each message
   foreach ($a_headers as $i => $header)  //while (list($i, $header) = each($a_headers))
     {
-    $message_icon = $attach_icon = '';
+    $message_icon = $attach_icon = $flagged_icon = '';
     $js_row_arr = array();
     $zebra_class = $i%2 ? 'even' : 'odd';
 
@@ -208,6 +206,9 @@
       $js_row_arr['unread'] = true;
     if ($header->answered)
       $js_row_arr['replied'] = true;
+    if ($header->flagged)
+      $js_row_arr['flagged'] = true;
+
     // set message icon  
     if ($attrib['deletedicon'] && $header->deleted)
       $message_icon = $attrib['deletedicon'];
@@ -217,6 +218,11 @@
       $message_icon = $attrib['repliedicon'];
     else if ($attrib['messageicon'])
       $message_icon = $attrib['messageicon'];
+
+    if ($attrib['flaggedicon'] && $header->flagged)
+      $flagged_icon = $attrib['flaggedicon'];
+    else if ($attrib['unflaggedicon'] && !$header->flagged)
+      $flagged_icon = $attrib['unflaggedicon'];
     
     // set attachment icon
     if ($attrib['attachmenticon'] && preg_match("/multipart\/[mr]/i", $header->ctype))
@@ -226,9 +232,11 @@
                     $header->uid,
                     $header->seen ? '' : ' unread',
                     $header->deleted ? ' deleted' : '',
+                    $header->flagged ? ' flagged' : '',
                     $zebra_class);    
     
     $out .= sprintf("<td class=\"icon\">%s</td>\n", $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : '');
+
 
     if (!empty($header->charset))
       $IMAP->set_charset($header->charset);
@@ -246,6 +254,8 @@
         if (empty($cont)) $cont = Q(rcube_label('nosubject'));
         $cont = sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), $cont);
         }
+      else if ($col=='flag')
+        $cont = $flagged_icon ? sprintf($image_tag, $skin_path, $flagged_icon, '') : '';
       else if ($col=='size')
         $cont = show_bytes($header->$col);
       else if ($col=='date')
@@ -288,6 +298,10 @@
     $OUTPUT->set_env('repliedicon', $skin_path . $attrib['repliedicon']);
   if ($attrib['attachmenticon'])
     $OUTPUT->set_env('attachmenticon', $skin_path . $attrib['attachmenticon']);
+  if ($attrib['flaggedicon'])
+    $OUTPUT->set_env('flaggedicon', $skin_path . $attrib['flaggedicon']);
+  if ($attrib['unflaggedicon'])
+    $OUTPUT->set_env('unflaggedicon', $skin_path . $attrib['unflaggedicon']);
   
   $OUTPUT->set_env('messages', $a_js_message_arr);
   $OUTPUT->set_env('coltypes', $a_show_cols);
@@ -353,6 +367,8 @@
     $a_msg_flags['deleted'] = $header->deleted ? 1 : 0;
     $a_msg_flags['unread'] = $header->seen ? 0 : 1;
     $a_msg_flags['replied'] = $header->answered ? 1 : 0;
+    $a_msg_flags['flagged'] = $header->flagged ? 1 : 0;
+    
     $OUTPUT->command('add_message_row',
       $header->uid,
       $a_msg_cols,
diff --git a/program/steps/mail/mark.inc b/program/steps/mail/mark.inc
index 830f1fe..ce4249d 100644
--- a/program/steps/mail/mark.inc
+++ b/program/steps/mail/mark.inc
@@ -22,7 +22,9 @@
   'undelete' => 'UNDELETED',
   'delete' => 'DELETED',
   'read' => 'SEEN',
-  'unread' => 'UNSEEN');
+  'unread' => 'UNSEEN',
+  'flagged' => 'FLAGGED',
+  'unflagged' => 'UNFLAGGED');
 
 if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_value('_flag', RCUBE_INPUT_POST)))
 {
diff --git a/skins/default/mail.css b/skins/default/mail.css
index a4d58bc..2f83578 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -456,7 +456,8 @@
   vertical-align: middle;
 }
 
-#messagelist tr td.icon
+#messagelist tr td.icon,
+#messagelist tr td.flag
 {
   width: 16px;
   vertical-align: middle;
diff --git a/skins/default/templates/mail.html b/skins/default/templates/mail.html
index a0f38fb..fe1c5b7 100644
--- a/skins/default/templates/mail.html
+++ b/skins/default/templates/mail.html
@@ -68,7 +68,9 @@
   unreadIcon="/images/icons/unread.png"
   deletedIcon="/images/icons/deleted.png"
   repliedIcon="/images/icons/replied.png"
-  attachmentIcon="/images/icons/attachment.png" />
+  attachmentIcon="/images/icons/attachment.png"
+  flaggedIcon="/images/icons/flagged.png"
+  unflaggedIcon="/images/icons/unflagged.png" />
 </div>
 
 <roundcube:if condition="config:preview_pane == true" />
@@ -112,6 +114,8 @@
   <ul class="toolbarmenu">
     <li><roundcube:button command="mark" prop="read" label="markread" classAct="active" /></li>
     <li><roundcube:button command="mark" prop="unread" label="markunread" classAct="active" /></li>
+    <li><roundcube:button command="mark" prop="flagged" label="markflagged" classAct="active" /></li>
+    <li><roundcube:button command="mark" prop="unflagged" label="markunflagged" classAct="active" /></li>
   </ul>
 </div>
 </div>

--
Gitblit v1.9.1