/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these librararies and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* Copyright (c) 1994,1995,1996 FUJITSU LIMITED */ /* All Rights Reserved */ /* * $XConsortium: SearchScopeList.C /main/15 1996/09/27 10:16:12 cde-hal $ * * Copyright (c) 1993 HAL Computer Systems International, Ltd. * All rights reserved. Unpublished -- rights reserved under * the Copyright Laws of the United States. USE OF A COPYRIGHT * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION * OR DISCLOSURE. * * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. USE, * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS * INTERNATIONAL, LTD. * * RESTRICTED RIGHTS LEGEND * Use, duplication, or disclosure by the Government is subject * to the restrictions as set forth in subparagraph (c)(l)(ii) * of the Rights in Technical Data and Computer Software clause * at DFARS 252.227-7013. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * */ #include "UAS.hh" #include "Support/UtilityFunctions.hh" #define C_Buffer #define L_Basic #define C_xList #define L_Support #define C_SearchScopeList #define C_SearchScopeAgent #define L_Agents #define C_UserPreference #define C_StringPref #define L_Preferences #define C_MessageMgr #define C_SearchScopeMgr #define C_EnvMgr #define L_Managers #include #include #ifdef SVR4 #ifndef USL #include #endif #endif #include #include #include "Other/XmStringLocalized.hh" #include "Managers/CatMgr.hh" #include "Registration.hh" // rtp - 4/24/95 : Added a very simple buffer class for use in // this module. (Original code written by swm.) SimpleBuffer::SimpleBuffer () : f_data(NULL), f_data_len(0) { } SimpleBuffer::~SimpleBuffer () { delete [] f_data; f_data = NULL; f_data_len = 0; } void SimpleBuffer::write (char *new_data) { int new_len = 0; if (f_data) new_len = strlen (f_data); new_len += strlen (new_data); // manual realloc char *new_buf = new char [new_len + 1]; if (f_data) (void) strcpy (new_buf, f_data); else *new_buf = 0; delete [] f_data; f_data = new_buf; (void) strcat (f_data, new_data); } char * SimpleBuffer::data () { return f_data; } SearchScopeList::SearchScopeList (SearchScopeAgent *ssa) : f_search_scope_agent (ssa) { f_buffer = new SimpleBuffer; } SearchScopeList::~SearchScopeList () { delete f_buffer; } void SearchScopeList::save() { List_Iterator i (this); UAS_SearchScope *scope; char scratch[256]; Buffer buffer, temp_buffer; // for each search scope do for (; i != NULL; i++) { scope = i.item(); if (scope->deleted() || scope->read_only()) continue; buffer.reset(); // Store the scope component mask. sprintf (scratch, "%d;", scope->search_zones().zones()); buffer.write (scratch, sizeof (char), strlen (scratch)); // get the list of bookcases for the current scope UAS_PtrList bcases = scope->bookcases(); // If there are no bookcases in the scope, there is a problem // somewhere; skip to the next scope. if (bcases.numItems() <= 0) continue; UAS_BookcaseEntry *bce; if(env().debug()) { cerr << endl; cerr << "Save Scope: " << scope->name(); } // loop for each bookcase in the search scope for (int bc = 0; bc < bcases.numItems(); bc++) { bce = bcases[bc]; // write bookcase id and name to buffer const char *name = bce->name(); const char *bid = bce->bid(); if (bc > 0) sprintf (scratch, "&%s(%s)", bid, name); else sprintf (scratch, "%s(%s)", bid, name); buffer.write(scratch, sizeof (char), strlen(scratch)); if(env().debug()) cerr << scratch; // See if individual books are selected. // Store the books by book number. UAS_ObjList booklist = bce->book_list(); // if there are no books--entire bookcase is selected if (booklist.numItems() > 0) { for (int bk = 0; bk < booklist.numItems(); bk++) { sprintf (scratch, ",%d", booklist[bk]); buffer.write(scratch, sizeof (char), strlen(scratch)); } if(env().debug()) cerr << scratch << endl; } } buffer.write ("\0", sizeof (char), 1); // Get the right preference object. sprintf (scratch, "Scope.%s", scope->name()); StringPref store (scratch); // Update its value. ON_DEBUG (printf ("WRITING: %s: %s\n", scratch, buffer.data())); store.value (buffer.data()); } // Now dump the name of each of the scopes. buffer.reset(); const char *name; for (i.reset(); i != NULL; i++) { if (i.item()->read_only()) continue; name = i.item()->name(); buffer.write (name, sizeof (char), strlen (name)); buffer.write (",", sizeof (char), 1); } // Backup and overwrite the trailing comma if there is one. if (buffer.point() != buffer.data()) buffer.point (buffer.point() - sizeof (char)); buffer.write ("\0", sizeof (char), 1); StringPref scopes ("Scopes"); // buffer used to write out all scope names SimpleBuffer output_buf; // if there's invalid scope names in f_buffer // to write out... if (f_buffer->data()) { // copy the invalid names to output buffer output_buf.write(f_buffer->data()); // if buffer with valid names is "empty", // i.e., only contains '\0' (see code above) if (buffer.length() == 1) { // overwrite the trailing comma at end of // the invalid scope names char *data = output_buf.data(); int len = strlen(data); data[len-1] = '\0'; } // otherwise concatanate the valid names else output_buf.write((char *)buffer.data()); } // otherwise just write out the valid names else output_buf.write((char *)buffer.data()); // write out all scope names to the prefs file scopes.value (output_buf.data()); ON_DEBUG (printf ("SCOPES: %s\n", output_buf.data())); // Flush the changes to disk. UserPreference::flush_preferences(); } void SearchScopeList::restore() { char scratch[1024]; char basename[256]; int i; UAS_SearchScope *s; // get the list of bookcase names UAS_List bcaseList = bookcaseList (); UAS_List libs = f_search_scope_agent->list(); // create the set of standard scopes UAS_PtrList bcases; // // Create the scope for the Current Section // s = f_search_scope_agent->create_scope( (char*)UAS_String(CATGETS(Set_Messages, 30, "Current Section")), bcases, f_section, FALSE); s->set_read_only(); // // Create a scope for All Libraries // bcases = f_search_scope_agent->bookcase_list(); s = f_search_scope_agent->create_scope( (char*)UAS_String(CATGETS(Set_SearchScopeAgent, 4, "All Libraries")), bcases, f_all, FALSE); s->set_read_only(); bcases.clear(); // // Create a scope for each infolib // for (i = 0; i < libs.length(); i++) { UAS_String libs_lid(libs[i]->lid()); s = f_search_scope_agent->create_infolib_scope(libs_lid); } // create all named scopes in preferences file create_named_scopes(); // rtp - 4/24/95 : if invalid scopes found then warn the user if (f_buffer->data()) search_scope_mgr().show_warning(True); // do not show dialog at this point--toplevel shell has not // yet been realized. Just set the flag so dialog can be // shown later. // message_mgr().warning_dialog ( // (char*)UAS_String(CATGETS(Set_Messages, 31, // "Ignoring invalid scopes in your profile."))); } // create all valid named scopes in preferences file void SearchScopeList::create_named_scopes() { char scratch[1024]; bool is_scope_valid; UAS_PtrList bookcase_list; UAS_BookcaseEntry *bce; // get list of scope names from preference file StringPref scopes ("Scopes"); UAS_String scope_list (scopes.value()); UAS_List scope_names = scope_list.splitFields (','); // reset invalid scope name buffer if (f_buffer != NULL) { delete f_buffer; f_buffer = new SimpleBuffer; } // retrieve scopes from preference file and validate each one for (int sname = 0; sname < scope_names.length(); sname++) { is_scope_valid = True; // Get the specified scope from preferences. UAS_String ss = *(UAS_String*) scope_names[sname]; sprintf (scratch, "Scope.%s", (char*)ss); StringPref scope (scratch); // Grab the component mask. unsigned int mask = 0; int i; sscanf (scope.value(), "%d%n", &mask, &i); if (mask == 0) { // rtp - 4/24/95 : bad mask means invalid scope is_scope_valid = FALSE; } // skip past component mask const char *scope_ptr = scope.value() + i; scope_ptr += 1; // get list of bookcases UAS_String scope_string(scope_ptr); UAS_Listbookcases = scope_string.splitFields ('&'); if(env().debug()) { cerr << endl; cerr << "Restore Scope." << (char*)ss; cerr << ": " << mask << ";"; } // loop once for each bookcase in search scope. create a // bookcase entry for each valid bookcase. if bookcase // is invalid, invalidate the scope. for (int bname = 0; bname < bookcases.length(); bname++) { UAS_String str = *(UAS_String*)bookcases[bname]; UAS_Listbc_list = str.splitFields (','); bce = create_bcase_entry(bc_list); if (bce == NULL) { is_scope_valid = False; if(env().debug()) cerr << " >>>>Scope is invalid" << endl; break; } bookcase_list.append(bce); } // get scope name UAS_String sn = *(UAS_String*)scope_names[sname]; if(is_scope_valid) { UAS_SearchScope *s = f_search_scope_agent->create_scope ( sn, bookcase_list, mask, False); } else { // rtp - 4/24/95 : otherwise store its name for use later; // see SearchScopeList::save routine above sprintf(scratch, "%s%s", (char*)sn, ","); f_buffer->write (scratch); } // reset list for next turn bookcase_list.clear(); } // for (int sname = 0) } // Check to see if bookcase is valid on system. If bid is valid, // return true, otherwise, return false. UAS_Pointer SearchScopeList::validate_bookcase(UAS_String &bid) { // validate bookcase id UAS_List libs = f_search_scope_agent->list(); for (int i = 0; i < libs.length(); i++) { UAS_List kids = libs[i]->children(); for (int j = 0; j < kids.length(); j++) { if(kids[j]->bid() == bid) { return kids[j]; } } } return (UAS_Pointer)NULL; } // Create a bookcase_entry and return it. // The input to this function is a bookcase list. // The first element is a bookcase id. All subsequent elements // are books: // BCID [book1 book2 book3 ...] // UAS_BookcaseEntry * SearchScopeList::create_bcase_entry(UAS_List &bc_list) { UAS_Pointer uas_bookcase; // get BCID--the first element in list UAS_String bs = *(UAS_String*)bc_list[0]; char buff[40]; sscanf((char*)bs,"%[^)(]", buff); UAS_String bid = UAS_String(buff, strlen(buff)); // validate BCID uas_bookcase = validate_bookcase(bid); if (uas_bookcase == (UAS_Pointer)NULL) return (UAS_BookcaseEntry*)NULL; // create new bookcase entry object UAS_BookcaseEntry *bce = new UAS_BookcaseEntry(uas_bookcase); if(env().debug()) cerr << "," << (char*)uas_bookcase->bid(); // Check to see if entire bookcase is selected or are there // individual books selected. if (bc_list.length() > 1) { // individual books have been selected. int book_num; UAS_ObjList booklist; for (int book = 1; book < bc_list.length(); book++) { UAS_String abook = *(UAS_String*)bc_list[book]; if(sscanf ((char*)abook, "%d", &book_num) == 1) { booklist.append (book_num); } } if(env().debug()) { for (int bk=0; bk < booklist.numItems(); bk++) cerr << "," << booklist[bk]; cerr << endl; } bce->set_book_list(booklist); } return bce; } // These routines are called from the SearchScopeAgent; They // maintain a list of BitHandles that directly coorespond to // the scopes maintained in the SearchScopeList (i.e., this). // It's crucial that if a scope is modified in SearchScopeList // (i.e., added, removed, etc.), it's corresponding BitHandle // in f_handle_list is modified in lock-step. -rtp // Note: the index is zero (0) based. -rtp void SearchScopeList::add_handle(BitHandle handle, int index) { // index of -1 means to append if (index == -1) { f_handle_list.append(handle); return; } List_Iterator h (f_handle_list); for (int i = 0; i < index; i++, h++); f_handle_list.insert_before (h, handle); } // Note: this routine must be called *before* the remove method // is called for the scope (...otherwise it won't find scope in // this, duh). -rtp void SearchScopeList::remove_handle(UAS_SearchScope *scope) { // first, find index into search scope list List_Iterator s (this); for (int i = 0; s != NULL && s.item() != scope; s++, i++); // if can't find scope in list then something is hosed if (s == NULL) return; // next, find the bit handle located at this index in handle list List_Iterator h (f_handle_list); for (int j = 0; j < i && h != NULL; j++, h++); // if this happens then something is hosed if (h == NULL) return; // and finally, remove it BitHandle bh = h.item(); f_handle_list.remove(bh); } // Routine to lookup BitHandle based on UAS_SearchScope * BitHandle SearchScopeList::lookup_handle(UAS_SearchScope *scope) { // first, find index into search scope list List_Iterator s (this); for (int i = 0; s != NULL && s.item() != scope; s++, i++); // if can't find scope in list then something is hosed if (s == NULL) return 0; // next, find the bit handle located at this index in handle list List_Iterator h (f_handle_list); for (int j = 0; j < i && h != NULL; j++, h++); // if this happens then something is hosed if (h == NULL) return 0; // and finally, return handle BitHandle bh = h.item(); return bh; }