Changeset 5101 in subversion


Ignore:
Timestamp:
Aug 19, 2011 9:42:34 AM (21 months ago)
Author:
alec
Message:
  • Implemented addressbook saved searches
Location:
branches/devel-saved-search/roundcubemail
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • branches/devel-saved-search/roundcubemail/SQL/mysql.initial.sql

    r4709 r5101  
    145145 
    146146 
     147-- Table structure for table `searches` 
     148 
     149CREATE TABLE `searches` ( 
     150 `search_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
     151 `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', 
     152 `type` int(3) NOT NULL DEFAULT '0', 
     153 `name` varchar(128) NOT NULL, 
     154 `data` text, 
     155 PRIMARY KEY(`search_id`), 
     156 CONSTRAINT `user_id_fk_searches` FOREIGN KEY (`user_id`) 
     157   REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE, 
     158 UNIQUE `uniqueness` (`user_id`, `type`, `name`) 
     159) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; 
     160 
     161 
    147162/*!40014 SET FOREIGN_KEY_CHECKS=1 */; 
  • branches/devel-saved-search/roundcubemail/SQL/mysql.update.sql

    r5069 r5101  
    145145TRUNCATE TABLE `messages`; 
    146146TRUNCATE TABLE `cache`; 
     147 
     148CREATE TABLE `searches` ( 
     149  `search_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
     150  `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', 
     151  `type` int(3) NOT NULL DEFAULT '0', 
     152  `name` varchar(128) NOT NULL, 
     153  `data` text, 
     154  PRIMARY KEY(`search_id`), 
     155  CONSTRAINT `user_id_fk_searches` FOREIGN KEY (`user_id`) 
     156    REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE, 
     157  UNIQUE `uniqueness` (`user_id`, `type`, `name`) 
     158) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; 
  • branches/devel-saved-search/roundcubemail/SQL/postgres.initial.sql

    r4603 r5101  
    226226CREATE INDEX messages_index_idx ON messages (user_id, cache_key, idx); 
    227227CREATE INDEX messages_created_idx ON messages (created); 
     228 
     229-- 
     230-- Sequence "searches_ids" 
     231-- Name: searches_ids; Type: SEQUENCE; Schema: public; Owner: postgres 
     232-- 
     233 
     234CREATE SEQUENCE search_ids 
     235    INCREMENT BY 1 
     236    NO MAXVALUE 
     237    NO MINVALUE 
     238    CACHE 1; 
     239 
     240-- 
     241-- Table "searches" 
     242-- Name: searches; Type: TABLE; Schema: public; Owner: postgres 
     243-- 
     244 
     245CREATE TABLE searches ( 
     246    search_id integer DEFAULT nextval('search_ids'::text) PRIMARY KEY, 
     247    user_id integer NOT NULL 
     248        REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE, 
     249    "type" smallint DEFAULT 0 NOT NULL, 
     250    name varchar(128) NOT NULL, 
     251    data text, 
     252    CONSTRAINT searches_user_id_key UNIQUE (user_id, "type", name) 
     253); 
  • branches/devel-saved-search/roundcubemail/SQL/postgres.update.sql

    r5069 r5101  
    101101TRUNCATE messages; 
    102102TRUNCATE cache; 
     103 
     104CREATE SEQUENCE search_ids 
     105    INCREMENT BY 1 
     106    NO MAXVALUE 
     107    NO MINVALUE 
     108    CACHE 1; 
     109 
     110CREATE TABLE searches ( 
     111    search_id integer DEFAULT nextval('search_ids'::text) PRIMARY KEY, 
     112    user_id integer NOT NULL 
     113        REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE, 
     114    "type" smallint DEFAULT 0 NOT NULL, 
     115    name varchar(128) NOT NULL, 
     116    data text, 
     117    CONSTRAINT searches_user_id_key UNIQUE (user_id, "type", name) 
     118); 
  • branches/devel-saved-search/roundcubemail/config/db.inc.php.dist

    r4410 r5101  
    6969$rcmail_config['db_sequence_messages'] = 'message_ids'; 
    7070 
     71$rcmail_config['db_sequence_searches'] = 'search_ids'; 
     72 
    7173 
    7274// end db config file 
  • branches/devel-saved-search/roundcubemail/program/include/rcube_user.php

    r5057 r5101  
    4848    private $rc; 
    4949 
     50    const SEARCH_ADDRESSBOOK = 1; 
     51    const SEARCH_MAIL = 2; 
    5052 
    5153    /** 
     
    552554    } 
    553555 
     556 
     557    /** 
     558     * Return a list of saved searches linked with this user 
     559     * 
     560     * @param int  $type  Search type 
     561     * 
     562     * @return array List of saved searches indexed by search ID 
     563     */ 
     564    function list_searches($type) 
     565    { 
     566        $result = array(); 
     567 
     568        $sql_result = $this->db->query( 
     569            "SELECT search_id AS id, ".$this->db->quoteIdentifier('name') 
     570            ." FROM ".get_table_name('searches') 
     571            ." WHERE user_id = ?" 
     572                ." AND ".$this->db->quoteIdentifier('type')." = ?" 
     573            ." ORDER BY ".$this->db->quoteIdentifier('name'), 
     574            (int) $this->ID, (int) $type); 
     575 
     576        while ($sql_arr = $this->db->fetch_assoc($sql_result)) { 
     577            $sql_arr['data'] = unserialize($sql_arr['data']); 
     578            $result[$sql_arr['id']] = $sql_arr; 
     579        } 
     580 
     581        return $result; 
     582    } 
     583 
     584 
     585    /** 
     586     * Return saved search data. 
     587     * 
     588     * @param int  $id  Row identifier 
     589     * 
     590     * @return array Data 
     591     */ 
     592    function get_search($id) 
     593    { 
     594        $sql_result = $this->db->query( 
     595            "SELECT ".$this->db->quoteIdentifier('name') 
     596                .", ".$this->db->quoteIdentifier('data') 
     597                .", ".$this->db->quoteIdentifier('type') 
     598            ." FROM ".get_table_name('searches') 
     599            ." WHERE user_id = ?" 
     600                ." AND search_id = ?", 
     601            (int) $this->ID, (int) $id); 
     602 
     603        while ($sql_arr = $this->db->fetch_assoc($sql_result)) { 
     604            return array( 
     605                'id'   => $id, 
     606                'name' => $sql_arr['name'], 
     607                'type' => $sql_arr['type'], 
     608                'data' => unserialize($sql_arr['data']), 
     609            ); 
     610        } 
     611 
     612        return null; 
     613    } 
     614 
     615 
     616    /** 
     617     * Deletes given saved search record 
     618     * 
     619     * @param  int  $sid  Search ID 
     620     * 
     621     * @return boolean True if deleted successfully, false if nothing changed 
     622     */ 
     623    function delete_search($sid) 
     624    { 
     625        if (!$this->ID) 
     626            return false; 
     627 
     628        $this->db->query( 
     629            "DELETE FROM ".get_table_name('searches') 
     630            ." WHERE user_id = ?" 
     631                ." AND search_id = ?", 
     632            (int) $this->ID, $sid); 
     633 
     634        return $this->db->affected_rows(); 
     635    } 
     636 
     637 
     638    /** 
     639     * Create a new saved search record linked with this user 
     640     * 
     641     * @param array $data Hash array with col->value pairs to save 
     642     * 
     643     * @return int  The inserted search ID or false on error 
     644     */ 
     645    function insert_search($data) 
     646    { 
     647        if (!$this->ID) 
     648            return false; 
     649 
     650        $insert_cols[]   = 'user_id'; 
     651        $insert_values[] = (int) $this->ID; 
     652        $insert_cols[]   = $this->db->quoteIdentifier('type'); 
     653        $insert_values[] = (int) $data['type']; 
     654        $insert_cols[]   = $this->db->quoteIdentifier('name'); 
     655        $insert_values[] = $data['name']; 
     656        $insert_cols[]   = $this->db->quoteIdentifier('data'); 
     657        $insert_values[] = serialize($data['data']); 
     658 
     659        $sql = "INSERT INTO ".get_table_name('searches') 
     660            ." (".join(', ', $insert_cols).")" 
     661            ." VALUES (".join(', ', array_pad(array(), sizeof($insert_values), '?')).")"; 
     662 
     663        call_user_func_array(array($this->db, 'query'), 
     664            array_merge(array($sql), $insert_values)); 
     665 
     666        return $this->db->insert_id('searches'); 
     667    } 
     668 
    554669} 
  • branches/devel-saved-search/roundcubemail/program/js/app.js

    r5049 r5101  
    330330 
    331331        this.enable_command('add', 'import', this.env.writable_source); 
    332         this.enable_command('list', 'listgroup', 'advanced-search', true); 
     332        this.enable_command('list', 'listgroup', 'listsearch', 'advanced-search', true); 
    333333 
    334334        // load contacts of selected source 
     
    522522 
    523523      case 'list': 
    524         if (this.task=='mail') { 
    525           if (!this.env.search_request || (props && props != this.env.mailbox)) 
    526             this.reset_qsearch(); 
    527  
     524        this.reset_qsearch(); 
     525        if (this.task == 'mail') { 
    528526          this.list_mailbox(props); 
    529527 
     
    532530        } 
    533531        else if (this.task == 'addressbook') { 
    534           if (!this.env.search_request || (props != this.env.source)) 
    535             this.reset_qsearch(); 
    536  
    537532          this.list_contacts(props); 
    538           this.enable_command('add', 'import', this.env.writable_source); 
    539533        } 
    540534        break; 
     
    1004998 
    1005999      case 'listgroup': 
     1000        this.reset_qsearch(); 
    10061001        this.list_contacts(props.source, props.id); 
    10071002        break; 
     
    19841979      url += '&_refresh=1'; 
    19851980 
    1986     this.select_folder(mbox, this.env.mailbox); 
     1981    this.select_folder(mbox); 
    19871982    this.env.mailbox = mbox; 
    19881983 
     
    34353430    this.env.qsearch = null; 
    34363431    this.env.search_request = null; 
     3432    this.env.search_id = null; 
    34373433  }; 
    34383434 
     
    38093805  this.list_contacts = function(src, group, page) 
    38103806  { 
    3811     var add_url = '', 
     3807    var folder, add_url = '', 
    38123808      target = window; 
    38133809 
     
    38253821      page = this.env.current_page = 1; 
    38263822 
    3827     this.select_folder((group ? 'G'+src+group : src), (this.env.group ? 'G'+this.env.source+this.env.group : this.env.source)); 
     3823    if (this.env.search_id) 
     3824      folder = 'S'+this.env.search_id; 
     3825    else 
     3826      folder = group ? 'G'+src+group : src; 
     3827 
     3828    this.select_folder(folder); 
    38283829 
    38293830    this.env.source = src; 
     
    38703871      url += '&_gid='+group; 
    38713872 
    3872     // also send search request to get the right messages  
    3873     if (this.env.search_request)  
     3873    // also send search request to get the right messages 
     3874    if (this.env.search_request) 
    38743875      url += '&_search='+this.env.search_request; 
    38753876 
     
    40654066  this.group_create = function() 
    40664067  { 
    4067     if (!this.gui_objects.folderlist) 
    4068       return; 
    4069  
    4070     if (!this.name_input) { 
    4071       this.name_input = $('<input>').attr('type', 'text'); 
    4072       this.name_input.bind('keydown', function(e){ return rcmail.add_input_keydown(e); }); 
    4073       this.name_input_li = $('<li>').addClass('contactgroup').append(this.name_input); 
    4074  
    4075       var li = this.get_folder_li(this.env.source) 
    4076       this.name_input_li.insertAfter(li); 
    4077     } 
    4078  
    4079     this.name_input.select().focus(); 
     4068    this.add_input_row('contactgroup'); 
    40804069  }; 
    40814070 
     
    41234112  }; 
    41244113 
     4114  // @TODO: maybe it would be better to use popup instead of inserting input to the list? 
     4115  this.add_input_row = function(type) 
     4116  { 
     4117    if (!this.gui_objects.folderlist) 
     4118      return; 
     4119 
     4120    if (!this.name_input) { 
     4121      this.name_input = $('<input>').attr('type', 'text').data('tt', type); 
     4122      this.name_input.bind('keydown', function(e){ return rcmail.add_input_keydown(e); }); 
     4123      this.name_input_li = $('<li>').addClass(type).append(this.name_input); 
     4124 
     4125      var li = type == 'contactsearch' ? $('li:last', this.gui_objects.folderlist) : this.get_folder_li(this.env.source); 
     4126      this.name_input_li.insertAfter(li); 
     4127    } 
     4128 
     4129    this.name_input.select().focus(); 
     4130  }; 
     4131 
    41254132  // handler for keyboard events on the input field 
    41264133  this.add_input_keydown = function(e) 
    41274134  { 
    4128     var key = rcube_event.get_keycode(e); 
     4135    var key = rcube_event.get_keycode(e), 
     4136      input = $(e.target), itype = input.data('tt'); 
    41294137 
    41304138    // enter 
    41314139    if (key == 13) { 
    4132       var newname = this.name_input.val(); 
     4140      var newname = input.val(); 
    41334141 
    41344142      if (newname) { 
    41354143        var lock = this.set_busy(true, 'loading'); 
    4136         if (this.env.group_renaming) 
     4144 
     4145        if (itype == 'contactsearch') 
     4146          this.http_post('search-create', '_search='+urlencode(this.env.search_request)+'&_name='+urlencode(newname), lock); 
     4147        else if (this.env.group_renaming) 
    41374148          this.http_post('group-rename', '_source='+urlencode(this.env.source)+'&_gid='+urlencode(this.env.group)+'&_name='+urlencode(newname), lock); 
    41384149        else 
     
    44504461  this.unselect_directory = function() 
    44514462  { 
    4452     if (this.env.address_sources.length > 1 || this.env.group != '') { 
    4453       this.select_folder('', (this.env.group ? 'G'+this.env.source+this.env.group : this.env.source)); 
    4454       this.env.group = ''; 
    4455       this.env.source = ''; 
    4456     } 
     4463    this.select_folder(''); 
     4464    this.enable_command('search-delete', false); 
     4465    this.env.group = ''; 
     4466    this.env.source = ''; 
     4467  }; 
     4468 
     4469  // callback for creating a new saved search record 
     4470  this.insert_saved_search = function(name, id) 
     4471  { 
     4472    this.reset_add_input(); 
     4473 
     4474    var key = 'S'+id, 
     4475      link = $('<a>').attr('href', '#') 
     4476        .attr('rel', id) 
     4477        .click(function() { return rcmail.command('listsearch', id, this); }) 
     4478        .html(name), 
     4479      li = $('<li>').attr({id: 'rcmli'+key.replace(this.identifier_expr, '_'), 'class': 'contactsearch'}) 
     4480        .append(link), 
     4481      prop = {name:name, id:id, li:li[0]}; 
     4482 
     4483    this.add_saved_search_row(prop, li); 
     4484    this.select_folder('S'+id); 
     4485    this.enable_command('search-delete', true); 
     4486    this.env.search_id = id; 
     4487 
     4488    this.triggerEvent('abook_search_insert', prop); 
     4489  }; 
     4490 
     4491  // add saved search row to the list, with sorting 
     4492  this.add_saved_search_row = function(prop, li, reloc) 
     4493  { 
     4494    var row, sibling, name = prop.name.toUpperCase(); 
     4495 
     4496    // When renaming groups, we need to remove it from DOM and insert it in the proper place 
     4497    if (reloc) { 
     4498      row = li.clone(true); 
     4499      li.remove(); 
     4500    } 
     4501    else 
     4502      row = li; 
     4503 
     4504    $('li[class~="contactsearch"]', this.gui_objects.folderlist).each(function(i, elem) { 
     4505      if (!sibling) 
     4506        sibling = this.previousSibling; 
     4507 
     4508      if (name >= $(this).text().toUpperCase()) 
     4509        sibling = elem; 
     4510      else 
     4511        return false; 
     4512    }); 
     4513 
     4514    if (sibling) 
     4515      row.insertAfter(sibling); 
     4516    else 
     4517      row.appendTo(this.gui_objects.folderlist); 
     4518  }; 
     4519 
     4520  // creates an input for saved search name 
     4521  this.search_create = function() 
     4522  { 
     4523    this.add_input_row('contactsearch'); 
     4524  }; 
     4525 
     4526  this.search_delete = function() 
     4527  { 
     4528    if (this.env.search_request) { 
     4529      var lock = this.set_busy(true, 'savedsearchdeleting'); 
     4530      this.http_post('search-delete', '_sid='+urlencode(this.env.search_id), lock); 
     4531    } 
     4532  }; 
     4533 
     4534  // callback from server upon search-delete command 
     4535  this.remove_search_item = function(id) 
     4536  { 
     4537    var li, key = 'S'+id; 
     4538    if ((li = this.get_folder_li(key))) { 
     4539      this.triggerEvent('search_delete', { id:id, li:li }); 
     4540 
     4541      li.parentNode.removeChild(li); 
     4542    } 
     4543 
     4544    this.env.search_id = null; 
     4545    this.env.search_request = null; 
     4546    this.list_contacts_clear(); 
     4547    this.reset_qsearch(); 
     4548    this.enable_command('search-delete', 'search-create', false); 
     4549  }; 
     4550 
     4551  this.listsearch = function(id) 
     4552  { 
     4553    var folder, lock = this.set_busy(true, 'searching'); 
     4554 
     4555    if (this.contact_list) { 
     4556      this.list_contacts_clear(); 
     4557    } 
     4558 
     4559    this.reset_qsearch(); 
     4560    this.select_folder('S'+id); 
     4561 
     4562    // reset vars 
     4563    this.env.current_page = 1; 
     4564    this.http_request('search', '_sid='+urlencode(id), lock); 
    44574565  }; 
    44584566 
     
    52005308 
    52015309  // mark a mailbox as selected and set environment variable 
    5202   this.select_folder = function(name, old, prefix) 
     5310  this.select_folder = function(name, prefix) 
    52035311  { 
    52045312    if (this.gui_objects.folderlist) { 
    52055313      var current_li, target_li; 
    52065314 
    5207       if ((current_li = this.get_folder_li(old, prefix))) { 
    5208         $(current_li).removeClass('selected').addClass('unfocused'); 
     5315      if ((current_li = $('li.selected', this.gui_objects.folderlist))) { 
     5316        current_li.removeClass('selected').addClass('unfocused'); 
    52095317      } 
    52105318      if ((target_li = this.get_folder_li(name, prefix))) { 
     
    52135321 
    52145322      // trigger event hook 
    5215       this.triggerEvent('selectfolder', { folder:name, old:old, prefix:prefix }); 
     5323      this.triggerEvent('selectfolder', { folder:name, prefix:prefix }); 
    52165324    } 
    52175325  }; 
     
    57605868 
    57615869          if (response.action == 'list' || response.action == 'search') { 
     5870            this.enable_command('search-create', this.env.source == ''); 
     5871            this.enable_command('search-delete', this.env.search_id); 
    57625872            this.update_group_commands(); 
    57635873            this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount }); 
  • branches/devel-saved-search/roundcubemail/program/localization/en_US/labels.inc

    r5040 r5101  
    141141$labels['markflagged']      = 'As flagged'; 
    142142$labels['markunflagged']    = 'As unflagged'; 
    143 $labels['messageactions']   = 'More actions...'; 
     143$labels['moreactions']      = 'More actions...'; 
    144144 
    145145$labels['select'] = 'Select'; 
     
    315315$labels['exportvcards']   = 'Export contacts in vCard format'; 
    316316$labels['newcontactgroup'] = 'Create new contact group'; 
    317 $labels['groupactions']   = 'Actions for contact groups...'; 
    318317$labels['grouprename']    = 'Rename group'; 
    319318$labels['groupdelete']    = 'Delete group'; 
     
    327326$labels['groups'] = 'Groups'; 
    328327$labels['personaladrbook'] = 'Personal Addresses'; 
     328 
     329$labels['searchsave'] = 'Save search'; 
     330$labels['searchdelete'] = 'Delete search'; 
    329331 
    330332$labels['import'] = 'Import'; 
  • branches/devel-saved-search/roundcubemail/program/localization/en_US/messages.inc

    r5022 r5101  
    140140$messages['grouprenamed'] = 'Group renamed successfully.'; 
    141141$messages['groupcreated'] = 'Group created successfully.'; 
     142$messages['savedsearchdeleted'] = 'Saved search deleted successfully.'; 
     143$messages['savedsearchdeleteerror'] = 'Could not delete saved search.'; 
     144$messages['savedsearchdcreated'] = 'Saved search created successfully.'; 
     145$messages['savedsearchcreateerror'] = 'Could not create saved search.'; 
    142146$messages['messagedeleted'] = 'Message(s) deleted successfully.'; 
    143147$messages['messagemoved'] = 'Message(s) moved successfully.'; 
  • branches/devel-saved-search/roundcubemail/program/steps/addressbook/func.inc

    r5058 r5101  
    222222    } 
    223223 
    224     $OUTPUT->set_env('contactgroups', $jsdata);  
     224    $line_templ = html::tag('li', array( 
     225        'id' => 'rcmliS%s', 'class' => '%s'), 
     226        html::a(array('href' => '#', 'rel' => 'S%s', 
     227            'onclick' => "return ".JS_OBJECT_NAME.".command('listsearch', '%s', this)"), '%s')); 
     228 
     229    // Saved searches 
     230    $sources = $RCMAIL->user->list_searches(rcube_user::SEARCH_ADDRESSBOOK); 
     231    foreach ($sources as $j => $source) { 
     232        $id = $source['id']; 
     233        $js_id = JQ($id); 
     234 
     235        // set class name(s) 
     236        $class_name = 'contactsearch'; 
     237        if ($current === $id) 
     238            $class_name .= ' selected'; 
     239        if ($source['class_name']) 
     240            $class_name .= ' ' . $source['class_name']; 
     241 
     242        $out .= sprintf($line_templ, 
     243            html_identifier($id), 
     244            $class_name, 
     245            $id, 
     246            $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id))); 
     247    } 
     248 
     249    $OUTPUT->set_env('contactgroups', $jsdata); 
    225250    $OUTPUT->add_gui_object('folderlist', $attrib['id']); 
    226251    // add some labels to client 
     
    740765    'group-addmembers' => 'groups.inc', 
    741766    'group-delmembers' => 'groups.inc', 
     767    'search-create' => 'search.inc', 
     768    'search-delete' => 'search.inc', 
    742769)); 
  • branches/devel-saved-search/roundcubemail/program/steps/addressbook/search.inc

    r4986 r5101  
    2222*/ 
    2323 
     24if ($RCMAIL->action == 'search-create') { 
     25    $id   = get_input_value('_search', RCUBE_INPUT_POST); 
     26    $name = get_input_value('_name', RCUBE_INPUT_POST, true); 
     27 
     28    if (($params = $_SESSION['search_params']) && $params['id'] == $id) { 
     29 
     30        $data = array( 
     31            'type' => rcube_user::SEARCH_ADDRESSBOOK, 
     32            'name' => $name, 
     33            'data' => array( 
     34                'fields' => $params['data'][0], 
     35                'search' => $params['data'][1], 
     36            ), 
     37        ); 
     38 
     39        $result = $RCMAIL->user->insert_search($data); 
     40    } 
     41 
     42    if ($result) { 
     43        $OUTPUT->show_message('savedsearchcreated', 'confirmation'); 
     44        $OUTPUT->command('insert_saved_search', Q($name), Q($result)); 
     45    } 
     46    else 
     47        $OUTPUT->show_message('savedsearchcreateerror', 'error'); 
     48 
     49    $OUTPUT->send(); 
     50} 
     51 
     52if ($RCMAIL->action == 'search-delete') { 
     53    $id = get_input_value('_sid', RCUBE_INPUT_POST); 
     54 
     55    $result = $RCMAIL->user->delete_search($id); 
     56 
     57    if ($result) { 
     58        $OUTPUT->show_message('savedsearchdeleted', 'confirmation'); 
     59        $OUTPUT->command('remove_search_item', Q($id)); 
     60    } 
     61    else 
     62        $OUTPUT->show_message('savedsearchdeleteerror', 'error'); 
     63 
     64    $OUTPUT->send(); 
     65} 
     66 
     67 
    2468if (!isset($_GET['_form'])) { 
    2569    rcmail_contact_search(); 
     
    3579 
    3680    $adv = isset($_POST['_adv']); 
    37  
     81    $sid = get_input_value('_sid', RCUBE_INPUT_GET); 
     82 
     83    // get search criteria from saved search 
     84    if ($sid && ($search = $RCMAIL->user->get_search($sid))) { 
     85        $fields = $search['data']['fields']; 
     86        $search = $search['data']['search']; 
     87    } 
    3888    // get fields/values from advanced search form 
    39     if ($adv) { 
     89    else if ($adv) { 
    4090        foreach (array_keys($_POST) as $key) { 
    4191            $s = trim(get_input_value($key, RCUBE_INPUT_POST, true)); 
     
    146196    // save search settings in session 
    147197    $_SESSION['search'][$search_request] = $search_set; 
     198    $_SESSION['search_params'] = array('id' => $search_request, 'data' => array($fields, $search)); 
    148199    $_SESSION['page'] = 1; 
    149200 
     
    163214    $OUTPUT->command('set_env', 'pagecount', ceil($result->count / $CONFIG['pagesize'])); 
    164215    $OUTPUT->command('set_rowcount', rcmail_get_rowcount_text($result)); 
     216    $OUTPUT->command('set_env', 'search_id', $sid); 
    165217 
    166218    // unselect currently selected directory/group 
    167     $OUTPUT->command('unselect_directory'); 
     219    if (!$sid) 
     220        $OUTPUT->command('unselect_directory'); 
    168221    $OUTPUT->command('update_group_commands'); 
    169222 
  • branches/devel-saved-search/roundcubemail/skins/default/addressbook.css

    r5041 r5101  
    110110#directorylistbox input 
    111111{ 
    112   margin: 2px; 
     112  margin: 0px; 
     113  font-size: 11px; 
    113114  width: 90%; 
    114115} 
     
    166167{ 
    167168  padding-left: 15px; 
    168   background-position: 20px -144px; 
     169  background-position: 20px -143px; 
     170} 
     171 
     172#directorylist li.contactsearch 
     173{ 
     174  background-position: 6px -162px; 
    169175} 
    170176 
  • branches/devel-saved-search/roundcubemail/skins/default/includes/messagetoolbar.html

    r4808 r5101  
    2020<roundcube:button name="markmenulink" id="markmenulink" type="link" class="button markmessage" title="markmessages" onclick="rcmail_ui.show_popup('markmenu');return false" content=" " />                                                                    
    2121<roundcube:endif /> 
    22 <roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button messagemenu" title="messageactions" onclick="rcmail_ui.show_popup('messagemenu');return false" content=" " /> 
     22<roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button messagemenu" title="moreactions" onclick="rcmail_ui.show_popup('messagemenu');return false" content=" " /> 
    2323<roundcube:if condition="template:name == 'message'" /> 
    2424<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mboxlist" folder_filter="mail" /> 
  • branches/devel-saved-search/roundcubemail/skins/default/templates/addressbook.html

    r4882 r5101  
    5959<div class="boxfooter"> 
    6060  <roundcube:button command="group-create" type="link" title="newcontactgroup" class="buttonPas addgroup" classAct="button addgroup" content=" " /> 
    61   <roundcube:button name="groupmenulink" id="groupmenulink" type="link" title="groupactions" class="button groupactions" onclick="rcmail_ui.show_popup('groupmenu');return false" content=" " /> 
     61  <roundcube:button name="groupmenulink" id="groupmenulink" type="link" title="moreactions" class="button groupactions" onclick="rcmail_ui.show_popup('groupmenu');return false" content=" " /> 
    6262</div> 
    6363</div> 
     
    100100    <li><roundcube:button command="group-rename" label="grouprename" classAct="active" /></li> 
    101101    <li><roundcube:button command="group-delete" label="groupdelete" classAct="active" /></li> 
     102    <li class="separator_above"><roundcube:button command="search-create" label="searchsave" classAct="active" /></li> 
     103    <li><roundcube:button command="search-delete" label="searchdelete" classAct="active" /></li> 
    102104    <roundcube:container name="groupoptions" id="groupoptionsmenu" /> 
    103105  </ul> 
Note: See TracChangeset for help on using the changeset viewer.