From 016e174f1c8c93c4e143a63be6f32caa77e67dcc Mon Sep 17 00:00:00 2001 From: "slamm%netscape.com" Date: Wed, 26 Aug 1998 18:35:54 +0000 Subject: [PATCH] Remove the old-style bookmarks. RDF is the way. git-svn-id: svn://10.0.0.236/trunk@8530 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/cmd/winfe/mkfiles32/mozilla.mak | 1 - mozilla/cmd/winfe/winproto.h | 1 - mozilla/include/bkmks.h | 700 --- mozilla/include/client.h | 1 - mozilla/include/hotlist.h | 250 - mozilla/include/shist.h | 1 - mozilla/lib/libmisc/Makefile | 3 - mozilla/lib/libmisc/Makefile.in | 5 +- mozilla/lib/libmisc/bkmks.c | 7428 ----------------------- mozilla/lib/libmisc/bkmutils.c | 888 --- mozilla/lib/libmisc/glhist.c | 3 - mozilla/lib/libmisc/hotlist.c | 1455 ----- mozilla/lib/libmisc/shist.c | 36 - 13 files changed, 1 insertion(+), 10771 deletions(-) delete mode 100644 mozilla/include/bkmks.h delete mode 100644 mozilla/include/hotlist.h delete mode 100644 mozilla/lib/libmisc/bkmks.c delete mode 100644 mozilla/lib/libmisc/bkmutils.c delete mode 100644 mozilla/lib/libmisc/hotlist.c diff --git a/mozilla/cmd/winfe/mkfiles32/mozilla.mak b/mozilla/cmd/winfe/mkfiles32/mozilla.mak index fba837ef63d..9d9461b240e 100644 --- a/mozilla/cmd/winfe/mkfiles32/mozilla.mak +++ b/mozilla/cmd/winfe/mkfiles32/mozilla.mak @@ -967,7 +967,6 @@ $(OUTDIR)\mozilla.dep: $(DEPTH)\cmd\winfe\mkfiles32\mozilla.mak !endif $(DEPTH)\lib\libmisc\glhist.c - $(DEPTH)\lib\libmisc\hotlist.c $(DEPTH)\lib\libmisc\shist.c $(DEPTH)\lib\libmisc\undo.c diff --git a/mozilla/cmd/winfe/winproto.h b/mozilla/cmd/winfe/winproto.h index 7bb6209c669..2ff12057413 100755 --- a/mozilla/cmd/winfe/winproto.h +++ b/mozilla/cmd/winfe/winproto.h @@ -150,7 +150,6 @@ extern char * szLoadString (UINT iID, ResourceSwitcher *pSwticher = NULL); extern void fe_InitFileFormatTypes(void); extern CHelperApp * fe_AddNewFileFormatType(const char *mime_type,const char *subtype); extern void fe_CleanupFileFormatTypes(void); -extern HotlistStruct * fe_find_hotlist_root (HotlistStruct * pListTop, BOOL add_p, MWContext * context); // Get a file name given a type prefix and extension // Name is returned in static space --- user must not free diff --git a/mozilla/include/bkmks.h b/mozilla/include/bkmks.h deleted file mode 100644 index 791ebda4268..00000000000 --- a/mozilla/include/bkmks.h +++ /dev/null @@ -1,700 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ -#ifndef BKMKS_H -#define BKMKS_H - -#include "xp_mcom.h" -#include "ntypes.h" - -XP_BEGIN_PROTOS - -#define BM_LAST_CELL 0xFFFF /* See BMFE_RefreshCells */ - -typedef time_t BM_Date; - -typedef enum { - BM_Cmd_Invalid, /* XFE in particular likes to have an invalid - ID code as one of the entries here...*/ - - BM_Cmd_Open, /* Open a new bookmark file. */ - - BM_Cmd_ImportBookmarks, /* Import entries from another bookmark - file. */ - - BM_Cmd_SaveAs, /* Save these bookmarks into another file. */ - - BM_Cmd_Close, /* Close the bookmarks window. (NYI ###) */ - - BM_Cmd_Undo, /* Undo the last command. */ - BM_Cmd_Redo, /* Redo the last undone command. */ - - BM_Cmd_Cut, /* Cut the selected bookmarks. */ - BM_Cmd_Copy, /* Copy the selected bookmarks. */ - BM_Cmd_Paste, /* Paste in the most recent cut/copy. */ - BM_Cmd_Delete, /* Delete the selected bookmarks without - affecting the clipboard. */ - - BM_Cmd_SelectAllBookmarks, /* Select every bookmark in the window. */ - - BM_Cmd_Find, /* Find a string. */ - - BM_Cmd_FindAgain, /* Find the same string again. */ - - BM_Cmd_BookmarkProps, /* Bring up the properties window. */ - - BM_Cmd_GotoBookmark, /* Load the selected bookmark in a browser - window. */ - - /* Sort the bookmarks. NYI### */ - BM_Cmd_Sort_Name, - BM_Cmd_Sort_Name_Asc, - - BM_Cmd_Sort_Address, - BM_Cmd_Sort_Address_Asc, - - BM_Cmd_Sort_AddDate, - BM_Cmd_Sort_AddDate_Asc, - - BM_Cmd_Sort_LastVisit, - BM_Cmd_Sort_LastVisit_Asc, - - BM_Cmd_Sort_Natural, - - - BM_Cmd_InsertBookmark, /* Insert a new bookmark (or a new address if - in addressbook). */ - - BM_Cmd_InsertHeader, /* Insert a new header. */ - - BM_Cmd_InsertSeparator, /* Insert a separator. */ - - BM_Cmd_MakeAlias, /* Make an alias of this bookmark. */ - - BM_Cmd_SetAddHeader, /* Make the current header be the one where new - bookmarks are added. */ - - BM_Cmd_SetMenuHeader /* Make the current header be the one which the - pulldown menu is created from. */ - -} BM_CommandType; -#define BM_Cmd_SortBookmarks BM_Cmd_Sort_Name - -typedef enum -{ - BM_Sort_NONE = -1, - - BM_Sort_Name, - BM_Sort_Name_Asc, - - BM_Sort_Address, - BM_Sort_Address_Asc, - - BM_Sort_AddDate, - BM_Sort_AddDate_Asc, - - BM_Sort_LastVisit, - BM_Sort_LastVisit_Asc, - - BM_Sort_Natural - -} BM_SortType; - -/* The various types of bookmark entries (as returned by BM_GetType). */ - -typedef uint16 BM_Type; - -#define BM_TYPE_HEADER 0x0001 -#define BM_TYPE_URL 0x0002 -#define BM_TYPE_ADDRESS 0x0004 -#define BM_TYPE_SEPARATOR 0x0008 -#define BM_TYPE_ALIAS 0x0010 - - -/* This represents one line in the bookmarks window -- a URL, a - separater, an addressbook entry, a header, etc. It's also already - defined in ntypes.h, and some compilers bitch and moan about seeing it - twice, so I've commented it out here. */ -/* typedef struct BM_Entry_struct BM_Entry; */ - - - -/* information for the find dialog */ -typedef struct BM_FindInfo { - char* textToFind; - XP_Bool checkNickname; /* Meaningful only in addressbook */ - XP_Bool checkName; - XP_Bool checkLocation; - XP_Bool checkDescription; - XP_Bool matchCase; - XP_Bool matchWholeWord; - - BM_Entry* lastEntry; -} BM_FindInfo; - -struct BM_Entry_Focus { - BM_Entry* saveFocus; - XP_Bool foundSelection; -}; - -extern XP_Bool BM_IsHeader(BM_Entry* entry); -extern XP_Bool BM_IsUrl(BM_Entry* entry); -extern XP_Bool BM_IsAddress(BM_Entry* entry); -extern XP_Bool BM_IsSeparator(BM_Entry* entry); -extern XP_Bool BM_IsAlias(BM_Entry* entry); -extern XP_Bool BM_IsFolded(BM_Entry* entry); -extern XP_Bool BM_IsSelected(BM_Entry* entry); - - -/* Returns the state of whether this is a "changed URL"; that is, a URL whose - contents have apparently changed since we last visited it. */ - -#define BM_CHANGED_YES 1 -#define BM_CHANGED_NO 0 -#define BM_CHANGED_UNKNOWN -1 - -extern int32 BM_GetChangedState(BM_Entry* entry); - - - -/* Get/Set the header that is to be the root of the pulldown menu. */ -extern BM_Entry* BM_GetMenuHeader(MWContext* context); -extern void BM_SetMenuHeader(MWContext* context, BM_Entry* entry); - -/* Get/Set the header that is to be the container of new items added from - browser windows. */ -extern BM_Entry* BM_GetAddHeader(MWContext* context); -extern void BM_SetAddHeader(MWContext* context, BM_Entry* entry); - - -typedef void (*EntryFunc)(MWContext* context, BM_Entry* entry, void* closure); - - -/* Executes the given function on every single entry in the bookmark file. */ -extern void BM_EachEntryDo(MWContext* context, EntryFunc func, void* closure); - -/* Executes the given function for every entry that is selected. */ -extern void BM_EachSelectedEntryDo(MWContext* context, EntryFunc func, - void* closure); - -/* Executes the given function for every entry that is selected and is not a - descendent of a header that is not folded or selected. */ -extern void BM_EachProperSelectedEntryDo(MWContext* context, EntryFunc func, - void* closure, struct BM_Entry_Focus* bmFocus); - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* Front end stubs -- each FE needs to implement these. */ - -/* Refresh each cell between and including first and last in the bookmarks - widget (if now is TRUE, the FE is expected to redraw them BEFORE returning, - otherwise the FE can simply invalidate them and wait for the redraw to - happen). If BM_LAST_CELL is passed in as last, then it means paint from - the first to the end. */ -extern void BMFE_RefreshCells(MWContext* context, int32 first, int32 last, - XP_Bool now); - - -/* Resize the widget to accomodate "visibleCount" number of entries vertically - and the width of widest entry the actual widget should NOT change size, just - the size of the scrollable area under it */ -extern void BMFE_SyncDisplay(MWContext* context); - - -/* measure the item and assign the width and height required to draw it into - the widget into width and height. This is used only by BM_WidestEntry(); if - you don't need that call, you can just make this an empty stub. */ -extern void BMFE_MeasureEntry(MWContext* context, BM_Entry* entry, - uint32* width, uint32* height); - -/* Save the given bucket o' bits as the clipboard. This same bucket needs to - be returned later if BMFE_GetClipContents() is called. */ -extern void BMFE_SetClipContents(MWContext* context, void* buffer, - int32 length); - - -/* return the clipboard contents */ -extern void* BMFE_GetClipContents(MWContext* context, int32* length); - - -/* Copy the selected items from a history window to the clipboard (as bookmarks) */ -extern char *BM_ClipCopyHistorySelection( void *pHistCsr, uint32 *pSelections, int iCount, int *pSize, XP_Bool bLongFormat ); - -/* Insert the block into the list */ -extern void BM_DropBlockL( MWContext *pContext, char *pData, BM_Entry *firstSelected ); - -/* Create the bookmarks property window. If one already exists, just bring it - to the front. This will always be immediately followed by a call to - BMFE_EditItem(). */ -extern void BMFE_OpenBookmarksWindow(MWContext* context); - - -/* Edit the given item in the bookmarks property window. If there is no - bookmarks property window currently, then the FE should ignore this call. - If the bookmarks property window is currently displaying some other entry, - then it should save any changes made to that entry (by calling BM_SetName, - etc.) before loading up this entry. */ -extern void BMFE_EditItem(MWContext* context, BM_Entry* entry); - -/* The given entry is no longer valid (i.e., the user just deleted it). So, - the given pointer is about to become invalid, and the FE should remove any - references to it it may have. In particular, if it is the one being edited - in the bookmarks property window, then the FE should clear that window. */ -extern void BMFE_EntryGoingAway(MWContext* context, BM_Entry* entry); - - -/* The user has requested to view the given url. Show it to him in, using some - appropriate context. Url may be targeted to a different window */ -extern void BMFE_GotoBookmark(MWContext* context, - const char* url, const char* target); - - -/* Create the find dialog, and fill it in as specified in the given - structure. When the user hits the "Find" button in the dialog, call - BM_DoFindBookmark. */ -extern void* BMFE_OpenFindWindow(MWContext* context, BM_FindInfo* findInfo); - - -/* Make sure that the given entry is visible. */ -extern void BMFE_ScrollIntoView(MWContext* context, BM_Entry* entry); - - -/* The list of bookmarks has changed somehow, so any "bookmarks" menu needs to - be recreated. This should be a cheap call, just setting a flag in the FE so - that it knows to recreate the menu later (like, when the user tries to view - it). Recreating it immediately would be bad, because this can get called - much more often than is reasonable. */ -extern void BMFE_BookmarkMenuInvalid(MWContext* context); - - -/* We're in the process of doing a What's Changed operation. The What's - Changed window should update to display the URL, the percentage (calculate - as done*100/total), and the total estimated time (given here as a - pre-formatted string). The What's Changed window should end up looking - something like this: - - Checking ... (<13> left) - {===================== } (progress bar) - - Estimated time remaining: <2 hours 13 minutes> - (Remaining time depends on the sites selected and - the network traffic). - - - [ Cancel ] - - It's up to the FE to notice the first time this is called and change its - window to display the info instead of the initial What's Changed screen. - - If the user ever hits Cancel (or does something equivilant, like destroys - the window), the FE must call BM_CancelWhatsChanged(). */ - -extern void BMFE_UpdateWhatsChanged(MWContext* context, - const char* url, /* If NULL, just display - "Checking..." */ - int32 done, int32 total, - const char* totaltime); - - - -/* We've finished processing What's Changed. The What's Changed window should - change to display the summary of what happened. It should look something - like this: - - Done checking <157> Bookmarks. - <134> documents were reached. - <27> documents have changed and are marked in blue. - - [ OK ] - - When the user clicks on the OK, the FE should just take down the window. - (It doesn't matter if the FE calls BM_CancelWhatsChanged(); it will be a - no-op in this situtation.) */ - -extern void BMFE_FinishedWhatsChanged(MWContext* context, int32 totalchecked, - int32 numreached, int32 numchanged); - -#ifdef XP_WIN -/* The current bookmarks file is about to change */ -extern void BMFE_ChangingBookmarksFile(void); - -/* The current bookmarks file has been changed */ -extern void BMFE_ChangedBookmarksFile(void); -#endif - -#ifdef XP_UNIX -/* Use these to know when to allow refresh */ -extern void BMFE_StartBatch(MWContext* context); -extern void BMFE_EndBatch(MWContext* context); -#endif - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - - -/* Initialize a new bookmarks context. (returns negative on failure) */ -extern int BM_InitializeBookmarksContext(MWContext* context); - - -/* Prepare to destroy a bookmarks context. Will save any changes that have - been made. */ -extern void BM_CleanupBookmarksContext(MWContext* context); - - -/* Set some FE data to associate with a bookmarks context. */ -extern void BM_SetFEData(MWContext* context, void* data); - -/* Get the FE data previously associated with a context. */ -extern void* BM_GetFEData(MWContext* context); - - -/* Create a new url entry. */ -extern BM_Entry* BM_NewUrl(const char* name, const char* address, - const char* content_type, BM_Date last_visit); - -/* Create a new header. */ -extern BM_Entry* BM_NewHeader(const char* name); - - -/* Create a copy of an existing bookmark. If the bookmark is a folder - it will also contain a copy of all of the bookmarks in the folder.*/ -extern BM_Entry* BM_CopyBookmark(MWContext* context, BM_Entry* original); - -/* Frees an entry. This should never be called unless you are sure the entry - has not been added to some header, and is not the object of some alias. In - other words, be sure nothing could possibly have a pointer to this it. - If the object is a header, this will also free all of its descendents. */ -extern void BM_FreeEntry(MWContext* context, BM_Entry* entry); - - -/* Get the type of this bookmark. (Returns one of the BM_TYPE_* values.) */ -extern BM_Type BM_GetType(BM_Entry* entry); - -extern char* BM_GetName(BM_Entry* entry); - -extern char* BM_GetAddress(BM_Entry* entry); -extern char* BM_GetTarget(BM_Entry* entry, XP_Bool recurse); -extern char* BM_GetDescription(BM_Entry* entry); - -extern char* BM_GetNickName(BM_Entry* entry); /* Only meaningful in address - book. */ - -/* Get the full name and address of the given entry (which must be an - address book entry or header). Result is returned in a newly allocated - string; free it with XP_FREE() when through. */ -extern char* BM_GetFullAddress(MWContext* context, BM_Entry* entry); - -/* These return prettily formated info about the bookmark. They each - return the result in a staticly allocated string, so if you call the - same function twice the results get stomped. */ -extern char* BM_PrettyLastVisitedDate(BM_Entry* entry); -extern char* BM_PrettyAddedOnDate(BM_Entry* entry); -extern char* BM_PrettyAliasCount(MWContext* context, BM_Entry* entry); - - -/* Get the root node of a context. */ -extern BM_Entry* BM_GetRoot(MWContext* context); - - -/* Given a node, return the first of its children (if any). */ -extern BM_Entry* BM_GetChildren(BM_Entry* entry); - -/* Given a node, return the next node that has the same parent (if any). */ -extern BM_Entry* BM_GetNext(BM_Entry* entry); - -/* Given a node, returns its parent (or NULL if this is the root) */ -extern BM_Entry* BM_GetParent(BM_Entry* entry); - -/* Does this node have a sibling somewhere below it? */ -extern XP_Bool BM_HasNext(BM_Entry* entry); - -/* Does this node have a sibling somewhere above it? Note that there is *not* - an API to actually get that sibling, as this is not a simple call. However, - determing the existance of such a child is easy, and that's what Windows - needs to paint its pipes. */ -extern XP_Bool BM_HasPrev(BM_Entry* entry); - - - -/* Routines to change the name/address/description of an entry. These routines - will take care of updating the display as necessary. */ -extern void BM_SetName(MWContext* context, BM_Entry* entry, - const char* newName); -extern void BM_SetAddress(MWContext* context, BM_Entry* entry, - const char* newAddress); -extern void BM_SetTarget(MWContext* context, BM_Entry* entry, - const char* newTarget); -extern void BM_SetDescription(MWContext* context, BM_Entry* entry, - const char* newDesc); - -/* Only meaningful in addressbook (on an address or header or alias to same) */ -extern XP_Bool BM_SetNickName(MWContext* context, BM_Entry* entry, - const char* newName); - -/* The user just hit "Cancel" on the properties window, which was editing - the given item. This gives the bookmarks code a chance to delete the - item if it was just newly created. */ -extern void BM_CancelEdit(MWContext* context, BM_Entry* entry); - - -/* fold or unfold the header according to "fold" and all its subfolders if - foldAll is TRUE */ -extern void BM_FoldHeader(MWContext* context, BM_Entry* entry, XP_Bool fold, - XP_Bool refresh, XP_Bool foldAll); - - -/* clear all the selection flags, and cause a redisplay if refresh is set. */ -extern void BM_ClearAllSelection(MWContext* context, XP_Bool refresh); - -/* Clear all the child selections of the passes header and redisplay if refresh - is set. */ -extern void BM_ClearAllChildSelection(MWContext* context, BM_Entry* at, - XP_Bool refresh); - -/* Select everything. */ -extern void BM_SelectAll(MWContext* context, XP_Bool refresh); - - -/* selects the item, call BMFE_Refresh on it if "refresh" and calls - BM_ClearSelection first if extend is FALSE */ -extern void BM_SelectItem(MWContext* context, BM_Entry* item, XP_Bool refresh, - XP_Bool extend, XP_Bool select); - -/* Adds a range of bookmarks to the current selection. To be called by the FE - when the user Shift-Clicks in the window. This will unselect everything and - then select a range of bookmarks, from the last bookmark that was selected - with BM_SelectItem to the one given here. */ -extern void BM_SelectRangeTo(MWContext* context, BM_Entry* item); - -/* toggles the selected state of the item, call BMFE_Refresh on it if "refresh" - and calls BM_ClearSelection if extend is FALSE */ -extern void BM_ToggleItem(MWContext* context, BM_Entry* item, XP_Bool refresh, - XP_Bool extend ); - -/* returns the first selected entry */ -extern BM_Entry* BM_FirstSelectedItem(MWContext* context); - - -extern BM_Date BM_GetLastVisited(BM_Entry *); -extern BM_Date BM_GetAdditionDate(BM_Entry *); - -/* return the number of bookmarks */ -extern int32 BM_GetCount(MWContext* context); - -/* return the number of visible bookmarks */ -extern int32 BM_GetVisibleCount(MWContext* context); - -/* returns an integer index of the item in the list */ -extern int32 BM_GetIndex(MWContext* context, BM_Entry* item); - -/* returns an integer index of the item in the list and does not pay attention - to the is_folded value */ -extern int32 BM_GetUnfoldedIndex(MWContext* context, BM_Entry* item); - -/* returns the object associated with the index returned by BM_GetIndex() */ -extern BM_Entry* BM_AtIndex(MWContext* context, int32 index); - -/* returns the object associated with the index returned by - BM_GetUnfoldedIndex() */ -extern BM_Entry* BM_AtUnfoldedIndex(MWContext* context, int32 index); - - -/* returns an integer depth of the item in the list starting - at zero */ -extern int32 BM_GetDepth(MWContext* context, BM_Entry* item); - - -/* Execute a find operation according to the data in the given structure. This - will cause the appropriate entry to be selected and made visible. */ -extern void BM_DoFindBookmark(MWContext* context, BM_FindInfo* findInfo); - -/* For addressbook only: find and return the entry (if any) for the e-mail - address within the given mailto: url. (used by libmsg) */ -extern BM_Entry* BM_FindAddress(MWContext* context, const char* mailtourl); - - -/* For addressbook only: edit the entry for the e-mail address within the - given mailto: url, creating the entry if necessary. (used by libmsg) */ -extern void BM_EditAddress(MWContext* context, const char* mailtourl); - - -/* For addressbook only: if the given list of addresses includes a nickname - from the addresses, then return a new string with the addresses expanded. - If expandfull is True, then all mailing list entries are expanded too, - otherwise, mailing list entries are only expanded to include their name. - (used by libmsg). */ -extern char* BM_ExpandHeaderString(MWContext* context, const char* value, - XP_Bool expandfull); - - -/* Checks every bookmark context for a url and updates the last accessed - time. (For use by global history code; FE's probably don't need this.) */ -extern void BM_UpdateBookmarksTime(URL_Struct* URL_s, BM_Date cur_time); - -/* returns TRUE if the second argument is a direct descendent of the first - argument, returns FALSE otherwise */ -extern XP_Bool BM_IsDescendent(MWContext* context, BM_Entry* parent, - BM_Entry* possible_child); - - -/* The front end can use this call to determine what the indentation depth is - needed to display all the icons in the bookmarks. The XFE uses this to - dynamically resize the icon column. In true C style, the number returned is - actually one bigger than the biggest depth the FE will ever get. */ -extern int BM_GetMaxDepth(MWContext* context); - - -/* This is called during a drag operation. The user is dragging some bookmarks - and is currently pointing at the given line. (If under is True, then the - user is really pointing between the given line and the next line.) This - returns TRUE if the FE should draw a box around the given line, and FALSE if - it should underline it. */ -extern XP_Bool BM_IsDragEffectBox(MWContext* context, int line, XP_Bool under); - - -/* Actually do a drop in a drag-n-drop reordering operation. The arguments are - the same as BM_IsDragEffectBox(); the selected items will be moved. */ -extern void BM_DoDrop(MWContext* ctnx, int line, XP_Bool under); - - - - -/* find and return the widest visible entry in the bookmarks tree. This makes - sense only if your FE has defined a meaningful BMFE_MeasureEntry(). */ -extern BM_Entry* BM_WidestEntry(MWContext* context); - - - -/* insert an item after another item in the bm if the insert_after item is NULL - or not found the item will be inserted at the end of the list */ -extern void BM_InsertItemAfter(MWContext* context, BM_Entry* insert_after, - BM_Entry* insertee); - -/* insert an item in a header if "insert_after" is a Header type, or after the - item if "insert after" is not a header type. if the insert_after item is - NULL or not found the item will be inserted at the end of the bm */ -extern void BM_InsertItemInHeaderOrAfterItem(MWContext* context, - BM_Entry* insert_after, - BM_Entry* insertee ); - -/* Cause the given item to be inserted at the end of the given header. The - header passed in here is usually BM_GetAddHeader(). */ -extern void BM_AppendToHeader(MWContext* context, BM_Entry* header, - BM_Entry* entry); - -extern void BM_PrependChildToHeader(MWContext* context, BM_Entry* parent, BM_Entry* child); - -/* Removes the given item from bookmarks without deleting it*/ -extern void BM_RemoveChildFromHeader(MWContext* context, BM_Entry* parent, BM_Entry* child); - -/* Cause the given bookmark to be displayed in a browser window somewhere. - The given item must be an URL (BM_IsUrl must return TRUE). */ -extern void BM_GotoBookmark(MWContext* context, BM_Entry* item); - - -/* Reads the hostlist from disk, what else? Pass in the bm filename and a - relative URL which represents the original location of the html file. If - you are reading the default bm you should pass in a file URL of the form - file://localhost/PATH */ -extern void BM_ReadBookmarksFromDisk(MWContext* context, const char* filename, - const char* relative_url); - -/* saves the bm to a file. If the given filename is NULL, then save it back to - where it was loaded from and only if changes have been made. Returns - negative on failure. */ -extern int32 BM_SaveBookmarks(MWContext* context, const char* filename); - - -/* Returns the filename that the bookmarks are saved in. */ -extern const char* BM_GetFileName(MWContext* context); - -/* read in a new bookmarks file (esp for LI use). */ -extern void BM_Open_File(MWContext* context, char* newFile); - -/* ability to set the modified to true or false (esp for LI use). */ -extern void BM_SetModified(MWContext* context, XP_Bool mod); - -/* Whether the file will be written when Save is called. */ -extern XP_Bool BM_Modified(MWContext* context); - -/* Convert a number of selections in a bm list into a block of memory that the - user can use for cut and paste operations */ -extern char* BM_ConvertSelectionsToBlock(MWContext* context, - XP_Bool bLongFormat, - int32* lTotalLen); - -/* Take a block of memory and insert the bm items it represents into the - current bm */ -extern void BM_InsertBlockAt(MWContext* context, char* pOriginalBlock, - BM_Entry* addTo, XP_Bool bLongFormat, - int32 lTotalLen); - - -/* select all aliases for an entry */ -extern void BM_SelectAliases(MWContext* context, BM_Entry* forEntry ); - - -/* Count how many aliases there are to the given entry. */ -extern int32 BM_CountAliases(MWContext* context, BM_Entry* forEntry); - - -/* Make an alias for each of the currently selected entries. */ -extern void BM_MakeAliases(MWContext* context); - - -/* Returns the real item that an alias points to. The given entry must be an - alias (BM_IsAlias must return TRUE on it). */ -extern BM_Entry* BM_GetAliasOriginal(BM_Entry*); - - - -/* Start a What's Changed operation. Before calling this routine, it's up to - the FE to present a dialog like this when What's Changed starts: - - Look for documents that have changed on: - (o) All bookmarks - ( ) Selected bookmarks - - [ Start Checking ] [ Cancel ] - - Then the FE calls this routine when the user clicks Start Checking. The FE - will immediately get called via BMFE_UpdateWhatsChanged(), and the FE should - change the dialog box's appearance to match. */ -extern int BM_StartWhatsChanged(MWContext* context, - XP_Bool do_only_selected); - - -/* Cancel a running What's Changed operation. */ -extern int BM_CancelWhatsChanged(MWContext* context); - - - -/* Returns whether the given command can be executed right now. Should be - used to decide whether to disable a menu item for this command. */ -extern XP_Bool BM_FindCommandStatus(MWContext* context, - BM_CommandType command); - -/* Execute the given command. */ -extern void BM_ObeyCommand(MWContext* context, BM_CommandType command ); - -/* Clean up the undo queue */ -void BM_ResetUndo(MWContext * context); - -XP_END_PROTOS - -#endif /* BMLIST_H */ diff --git a/mozilla/include/client.h b/mozilla/include/client.h index a84b421fa9e..eb2eea8ad3f 100644 --- a/mozilla/include/client.h +++ b/mozilla/include/client.h @@ -49,7 +49,6 @@ #include "net.h" #include "gui.h" #include "shist.h" -#include "hotlist.h" #include "glhist.h" #include "mime.h" diff --git a/mozilla/include/hotlist.h b/mozilla/include/hotlist.h deleted file mode 100644 index 31b4c3e11d3..00000000000 --- a/mozilla/include/hotlist.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#ifndef HOTLIST_H -#define HOTLIST_H - -#include "xp_mcom.h" -#include "ntypes.h" - -XP_BEGIN_PROTOS - -typedef enum HOT_Type { - HOT_URLType, HOT_HeaderType, HOT_SeparatorType } HOT_Type; - -typedef struct HotlistStruct_ { - HOT_Type type; - Bool is_folded; /* if it's a header is it folded? */ - XP_List *children; /* a list of children, only headers have these */ - char *name; /* a title */ - char *address; /* the URL address */ - char *description; /* random text */ - time_t last_visit; - time_t addition_date; - char *content_type; - struct HotlistStruct_ *parent; /* My hotlist parent */ - XP_List *lParent; /* The XP_List object that points to my parent or NULL */ -} HotlistStruct; - -/* tell the hotlist code that the hotlist has been modified - * so that it gets saved the next time SaveHotlist is called - */ -extern void HOT_SetModified(void); - -/* changes a entry to a header type from a non header type - * and vice versa. If the object was a header and - * has children, the children will be blown away. (very bad) - */ -extern void HOT_ChangeEntryType(HotlistStruct * entry, HOT_Type new_type); - -/* Fold or unfold a hotlist header - * - * set the Boolean to True to fold the list and - * False to unfold - */ -extern void HOT_FoldHeader(HotlistStruct * item, Bool fold); - -/* checks the hotlist for a url and updates the last accessed - * time - */ -extern void HOT_UpdateHotlistTime(URL_Struct *URL_s, time_t cur_time); - -/* Performs regular expression match on hotlist name and address - * fields. Returns the found object, or NULL if not - * found. - * - * start_obj specifies the object to start searching - * on. The start_num object WILL NOT be searched but all those - * after it will be. - * To search the whole list give NULL as start_obj. - * - * If headers became unfolded because of the search then redisplay_all - * will be set to TRUE - */ -extern HotlistStruct * HOT_SearchHotlist(char * search_string, - HotlistStruct * start_obj, - Bool * redisplay_all); - -/* returns TRUE if the second argument is a direct - * descendent of the first argument. - * - * returns FALSE otherwise - */ -extern Bool HOT_IsDescendent(HotlistStruct *parent, HotlistStruct *possible_child); - - -/* Reads the hostlist from disk, what else? - * - * pass in the hotlist filename and a relative URL which represents - * the original location of the html file. If you are reading the - * default hotlist you should pass in a file URL of the form - * file://localhost/PATH - * - */ -extern void HOT_ReadHotlistFromDisk (char * filename, char * relative_url); - -/* returns an integer index of the item in the list - */ -extern int HOT_GetIndex(HotlistStruct * item); - -/* returns an integer index of the item in the list - * and does not pay attention to the is_folded value - */ -extern int HOT_GetUnfoldedIndex(HotlistStruct * item); - -/* returns the object associated with the index returned by - * HOT_GetIndex() - */ -extern HotlistStruct * HOT_IndexOf(int index); - -/* returns the object associated with the index returned by - * HOT_GetUnfoldedIndex() - */ -extern HotlistStruct * HOT_UnfoldedIndexOf(int index); - -/* returns an integer depth of the item in the list starting at zero - */ -extern int HOT_GetDepth(HotlistStruct * item); - -/* return a pointer to the main hotlist list - * - * returns NULL if nothing has ever been - * added to the hotlist - */ -extern XP_List * HOT_GetHotlistList(void); - -/* saves the hotlist to a configuration file - */ -extern int HOT_SaveHotlist (char * filename); - -/* Free's the entire hotlist - */ -extern void HOT_FreeHotlist (void); - - -/* create a hotlist entry struct and fill it in with - * the passed in data - * - * returns NULL on out of memory error. - */ -extern HotlistStruct * -HOT_CreateEntry(HOT_Type type, - const char *name, - const char *address, - const char *content_type, - time_t last_visit); - -/* free's a hotlist entry - */ -extern void HOT_FreeEntry(HotlistStruct * entry); - -/* create a completely new copy of the entry passed in - */ -extern HotlistStruct * HOT_CopyEntry(HotlistStruct * entry); - -/* insert an item before another item in the hotlist - * - * if the insert_before item is NULL or not found the item - * will be inserted at the begining of the list - */ -extern void HOT_InsertItemBefore(HotlistStruct * insert_before, HotlistStruct * insertee); - -/* insert an item after another item in the hotlist - * - * if the insert_after item is NULL or not found the item - * will be inserted at the end of the list - */ -extern void HOT_InsertItemAfter(HotlistStruct * insert_after, HotlistStruct * insertee); - -/* insert an item in a header if "insert_after" is a - * Header type, or after the item if "insert after" is - * not a header type. - * - * if the insert_after item is NULL or not found the item - * will be inserted at the end of the hotlist - */ -extern void -HOT_InsertItemInHeaderOrAfterItem(HotlistStruct * insert_after, - HotlistStruct * insertee); - -/* remove an item from the hotlist and free's it - * - * returns TRUE on success, FALSE if not found - */ -extern Bool HOT_RemoveItem(HotlistStruct * old_item); - -/* remove an item from the hotlist and doesn't free it - * - * returns TRUE on success, FALSE if not found - */ -extern Bool HOT_RemoveItemFromList(HotlistStruct * old_item); - -/* move an item up in the list - */ -extern void HOT_MoveObjectUp(HotlistStruct * item); - -/* move an item down in the list - */ -extern void HOT_MoveObjectDown(HotlistStruct * item); - -/* returns True if the object can be moved Up - * False if the object cannot be moved Up or if - * it cannot be found in the list - */ -extern Bool HOT_ObjectCanGoUp(HotlistStruct * item); - -/* returns True if the object can be moved down - * False if the object cannot be moved down or if - * it cannot be found in the list - */ -extern Bool HOT_ObjectCanGoDown(HotlistStruct * item); - -/* Whether the file will be written when Save is called. */ -extern Bool HOT_Modified(void); - -/* - * Gets the top node of the hotlist -*/ -extern HotlistStruct* -HOT_GetHotlist (void); - - -/* - * Convert a number of selections in a hotlist list into a block of - * memory that the user can use for cut and paste operations - */ -extern char * -HOT_ConvertSelectionsToBlock(HotlistStruct ** list, - int iCount, - int bLongFormat, - int32 * lTotalLen); -/* - * Take a block of memory and insert the hotlist items it represents into - * the current hotlist - */ -extern void -HOT_InsertBlockAt(char * pOriginalBlock, - HotlistStruct * item, - int bLongFormat, - int32 lTotalLen); - -XP_END_PROTOS - -#endif /* HOTLIST_H */ - - diff --git a/mozilla/include/shist.h b/mozilla/include/shist.h index 532170bb76c..7585c202c6f 100644 --- a/mozilla/include/shist.h +++ b/mozilla/include/shist.h @@ -21,7 +21,6 @@ #include "xp_list.h" #include "ntypes.h" -#include "hotlist.h" /* see shistele.h for the structure definitions. :( diff --git a/mozilla/lib/libmisc/Makefile b/mozilla/lib/libmisc/Makefile index 42b00870833..0e19beedc90 100644 --- a/mozilla/lib/libmisc/Makefile +++ b/mozilla/lib/libmisc/Makefile @@ -23,12 +23,9 @@ MODULE = misc LIBRARY_NAME = misc CSRCS = \ - bkmutils.c \ glhist.c \ undo.c \ - bkmks.c \ shist.c \ - hotlist.c \ dirprefs.c \ $(NULL) diff --git a/mozilla/lib/libmisc/Makefile.in b/mozilla/lib/libmisc/Makefile.in index 48a2b7fd064..e5f6dd5d885 100644 --- a/mozilla/lib/libmisc/Makefile.in +++ b/mozilla/lib/libmisc/Makefile.in @@ -16,7 +16,7 @@ # Reserved. - + DEPTH = ../.. topsrcdir = @top_srcdir@ VPATH = @srcdir@ @@ -28,12 +28,9 @@ MODULE = misc LIBRARY_NAME = misc CSRCS = \ - bkmutils.c \ glhist.c \ undo.c \ - bkmks.c \ shist.c \ - hotlist.c \ dirprefs.c \ $(NULL) diff --git a/mozilla/lib/libmisc/bkmks.c b/mozilla/lib/libmisc/bkmks.c deleted file mode 100644 index 6b45cc7d2f4..00000000000 --- a/mozilla/lib/libmisc/bkmks.c +++ /dev/null @@ -1,7428 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -/* If you add code to this file, make sure it still builds on win16 debug - its - * code segment is too big. - */ - -#include "bkmks.h" -#include "net.h" -#include "xp_mcom.h" -#include "client.h" -#include "msgcom.h" -#include "undo.h" -#include "xp_hash.h" -#include "xpgetstr.h" -#include "glhist.h" -#include "libi18n.h" -#include "xp_qsort.h" -#include "intl_csi.h" - -#ifdef XP_MAC -#pragma warn_unusedarg off -#pragma warn_possunwant off -#endif - -#define INTL_SORT 1 -#ifdef INTL_SORT /* Added by ftang */ -#include "xplocale.h" -#endif - -extern int MK_OUT_OF_MEMORY; - -extern int XP_BKMKS_BOOKMARKS_CHANGED; -extern int XP_BKMKS_ADDRESSBOOK_CHANGED; -extern int XP_BKMKS_BOOKMARKS_CONFLICT; -extern int XP_BKMKS_ADDRESSBOOK_CONFLICT; -extern int XP_BKMKS_CANT_WRITE_ADDRESSBOOK; -extern int XP_BKMKS_CANT_WRITE_BOOKMARKS; - -/* added by L10N team */ -extern int XP_BKMKS_HOURS_AGO; -extern int XP_BKMKS_DAYS_AGO; -extern int XP_BKMKS_COUNTALIASES_MANY; -extern int XP_BKMKS_COUNTALIASES_ONE; -extern int XP_BKMKS_COUNTALIASES_NONE; -extern int XP_BKMKS_INVALID_NICKNAME; -extern int XP_BKMKS_NICKNAME_ALREADY_EXISTS; -extern int XP_BKMKS_REMOVE_THIS_ITEMS_ALIASES; -extern int XP_BKMKS_REMOVE_SOME_ITEMS_ALIASES; -extern int XP_BKMKS_AUTOGENERATED_FILE; -extern int XP_BKMKS_READ_AND_OVERWRITE; -extern int XP_BKMKS_DO_NOT_EDIT; -extern int XP_BKMKS_NEW_HEADER; -extern int XP_BKMKS_NEW_BOOKMARK; -extern int XP_BKMKS_NOT_FOUND; -extern int XP_BKMKS_OPEN_BKMKS_FILE; -extern int XP_BKMKS_IMPORT_BKMKS_FILE; -extern int XP_BKMKS_IMPORT_ADDRBOOK; -extern int XP_BKMKS_SAVE_BKMKS_FILE; -extern int XP_BKMKS_SAVE_ADDRBOOK; -extern int XP_BKMKS_LESS_THAN_ONE_HOUR_AGO; - - -extern int XP_BKMKS_SOMEONE_S_BOOKMARKS; /* "%s%s's Bookmarks%s" */ -extern int XP_BKMKS_PERSONAL_BOOKMARKS; /* "%sPersonal Bookmarks%s" */ -extern int XP_BKMKS_SOMEONE_S_ADDRESSBOOK; /* "%s%s's Addressbook%s" */ -extern int XP_BKMKS_PERSONAL_ADDRESSBOOK; /* "%sPersonal Addressbook%s" */ - -extern int XP_BKMKS_BOOKMARK; -extern int XP_BKMKS_ENTRY; -extern int XP_BKMKS_SECONDS; -extern int XP_BKMKS_MINUTES; -extern int XP_BKMKS_HOURS_MINUTES; - -extern int XP_BKMKS_HEADER; -extern int XP_ADDRBOOK_HEADER; - - -#define SECONDS_PER_DAY 86400L -#define BMLIST_COOKIE "" -#define BM_ADDR_LIST_COOKIE "" -#define READ_BUFFER_SIZE 2048 -#define WRITE_BUFFER_SIZE 1848 /* Make this a few hundred less than - read buffer so we can be sure to - read the bookmarks back properly */ -#define DEF_NAME "Personal Bookmarks" /* L10N? This doesn't seem to be used. */ - -#ifdef FREEIF -#undef FREEIF -#endif -#define FREEIF(obj) do { if (obj) { XP_FREE (obj); obj = 0; }} while (0) - -#define BM_ATTR_FOLDED 0x0001 -#define BM_ATTR_SELECTED 0x0002 -#define BM_ATTR_ISNEW 0x0004 -#define BM_ATTR_FINDAFF 0x0008 /* This entry is temporarily unfolded only - as a result of the last find - operation. */ -#define BM_ATTR_HASALIASES 0x0010 /* Actually, being set only means that - this entry *might* have aliases. But - if an entry has aliases, this bit is - definitely set. */ -#define BM_ATTR_MARKED 0x0020 /* Random bit to temporarily mark a bunch of - items. */ -#define BM_ATTR_CHECKING 0x0040 /* In the midst of checking whether this - entry has changed. */ - - -#define BM_ISHEADER(bmStruct) \ - ((bmStruct) && ((bmStruct)->type == BM_TYPE_HEADER)) - -#define BM_ISURL(bmStruct) \ - ((bmStruct) && ((bmStruct)->type == BM_TYPE_URL)) - -#define BM_ISADDRESS(bmStruct) \ - ((bmStruct) && ((bmStruct)->type == BM_TYPE_ADDRESS)) - -#define BM_ISSEPARATOR(bmStruct) \ - ((bmStruct) && ((bmStruct)->type == BM_TYPE_SEPARATOR)) - -#define BM_ISALIAS(bmStruct) \ - ((bmStruct) && ((bmStruct)->type == BM_TYPE_ALIAS)) - -#define BM_ISFOLDED(bmStruct) \ - ((bmStruct) && ((bmStruct)->flags & BM_ATTR_FOLDED)) - -#define BM_ISSELECTED(bmStruct) \ - ((bmStruct) && ((bmStruct)->flags & BM_ATTR_SELECTED)) - -#define BM_SETFLAG(bmStruct, flag) \ - ((bmStruct) ? ((bmStruct)->flags |= (flag)) : 0) - -#define BM_CLEARFLAG(bmStruct, flag) \ - ((bmStruct) ? ((bmStruct)->flags &= ~(flag)) : 0) - -static int32 g_iNaturalIndexPool = 0; - -struct BM_Entry_struct -{ - BM_Type type; - - uint16 flags; - BM_Entry* next; - BM_Entry* parent; - char* name; - char* description; - BM_Date addition_date; - int32 iNaturalIndex; /* Index for user arranged "sort" */ - char* nickname; /* Used only by address book, alas. */ - - union { - struct BM_Header { - char* target; /* target */ - BM_Entry* children; /* a linked list of my children */ - uint32 childCount; /* the number of "children" */ - BM_Entry* lastChild; /* the last child in "children" */ - } header; - struct BM_Url { - char* address; /* address */ - char* target; /* target */ - char* content_type; /* content-type */ - BM_Date last_visit; /* when last visited */ - BM_Date last_modified; /* when the contents of the URL was last - modified. */ - } url; - struct BM_Address { - char* address; /* e-mail address */ - } address; - struct BM_Alias { - BM_Entry* original; /* the original bm */ - } alias; - } d; -}; - - -typedef struct BM_Frame { - BM_Entry* gBookmarks; /* root of the tree */ - XP_Bool gBookmarksModified; /* TRUE if the tree is modified */ - int32 gCount; /* number of entries in tree. If - negative, then need to be - recalculated. */ - int32 gVisCount; /* number of visible entries. If - negative, then need to be - recalculated. */ - int32 gSelectionCount; /* number of selected items. If - negative, then we're out of sync, - call bm_SyncSelection to - synchronize. */ - uint32 gSelectionMask; /* what types of items are selected - (invalid if gSelectionCount is - negative.)*/ - BM_FindInfo* gFindInfo; /* information for the find dialog */ - char* gFile; /* the file this data is from */ - void* gTemporary; - void* feData; - int32 max_depth; /* The number of levels in the heirarchy that - we currently display. (If zero, then we - don't know. */ - UndoState* undo; - MWContext* next; /* Next bookmarks context in master linked list. */ - XP_Bool unfoldedForFind; /* TRUE if some headers have been unfolded - as the result of a find operation. The - headers in question will have the - BM_ATTR_FINDAFF flag set.*/ - - BM_SortType enSortType; /* the sort field (a column or natural) */ - XP_Bool bSorting; - XP_HashTable aliasTable; - XP_HashTable nicknameTable; - int aliasID; - XP_Bool errorSavingBookmarks; - - int32 batch_depth; - int32 first_update_line; - int32 last_update_line; - - void* savetimer; - - BM_Entry* lastSelectedItem; - - BM_Entry* menuheader; /* Which header to use as the menu bar. */ - BM_Entry* addheader; /* Which entry to add new items into. */ - - XP_StatStruct laststat; /* Stat of the file when we loaded it in. */ - - - - struct BM_WhatsChangedInfo { - int32 total; - int32 numreached; - int32 numchanged; - time_t starttime; - } whatschanged; - -} BM_Frame; - - -#define CHKCONTEXT(context) \ -XP_ASSERT(context != NULL && (context->type == MWContextAddressBook || \ - context->type == MWContextBookmarks) && \ - context->bmframe != NULL); \ -if (!context || (context->type != MWContextAddressBook && \ - context->type != MWContextBookmarks) || \ - !context->bmframe) return 0; - -#define CHKCONTEXTVOID(context) \ -XP_ASSERT(context != NULL && (context->type == MWContextAddressBook || \ - context->type == MWContextBookmarks) && \ - context->bmframe != NULL); \ -if (!context || (context->type != MWContextAddressBook && \ - context->type != MWContextBookmarks) || \ - !context->bmframe) return; - - -/* Should probably be a macro, but putting the assert in the macro and - making this still be easy to use is just too painful. */ -static BM_Frame* -GETFRAME(MWContext* context) -{ - XP_ASSERT(context && - (context->type == MWContextBookmarks || - context->type == MWContextAddressBook) && - context->bmframe != NULL); - return (context && (context->type == MWContextBookmarks || - context->type == MWContextAddressBook)) - ? context->bmframe : NULL; -} - - -static void bm_CancelLastFind(MWContext* context); -static void bm_InsertItemAfter(MWContext* context, BM_Entry* insert_after, - BM_Entry* insertee, XP_Bool sync); -static void bm_SortSelected(MWContext* context, BM_SortType enSortType); -static void bm_SyncCount(MWContext* context); -static void bm_AddChildToHeaderSorted(MWContext* context, BM_Entry* parent, - BM_Entry* child); -static void bm_SortSilent(MWContext* context, BM_SortType enSortType ); - - - -XP_Bool -BM_IsHeader(BM_Entry* entry) -{ - return BM_ISHEADER(entry); -} - -XP_Bool -BM_IsUrl(BM_Entry* entry) -{ - return BM_ISURL(entry); -} - -XP_Bool -BM_IsAddress(BM_Entry* entry) -{ - return BM_ISADDRESS(entry); -} - -XP_Bool -BM_IsSeparator(BM_Entry* entry) -{ - return BM_ISSEPARATOR(entry); -} - -XP_Bool -BM_IsAlias(BM_Entry* entry) -{ - return BM_ISALIAS(entry); -} - -XP_Bool -BM_IsFolded(BM_Entry* entry) -{ - return BM_ISFOLDED(entry); -} - -XP_Bool -BM_IsSelected(BM_Entry* entry) -{ - return BM_ISSELECTED(entry); -} - - -int32 -BM_GetChangedState(BM_Entry* entry) -{ - if (BM_ISALIAS(entry)) { - entry = entry->d.alias.original; - } - if (BM_ISURL(entry)) { - if (entry->d.url.last_modified == 0 || entry->flags & BM_ATTR_CHECKING) { - return BM_CHANGED_UNKNOWN; - } - if (entry->d.url.last_visit < entry->d.url.last_modified) { - return BM_CHANGED_YES; - } - } - return BM_CHANGED_NO; -} - -/* globals */ -static MWContext* ContextList = NULL; - - -void -BM_SetFEData(MWContext* context, void* data) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - f->feData = data; -} - -void* -BM_GetFEData(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXT(context); - return f->feData; -} - - -/* creates a new empty bookmark entry */ -static BM_Entry* -bm_NewEntry(int16 type) -{ - BM_Entry* new_entry = XP_NEW_ZAP(BM_Entry); - if (!new_entry) return NULL; - XP_MEMSET(new_entry, 0, sizeof(BM_Entry)); - new_entry->type = type; - return new_entry; -} - -/* creates a new header bookmarks entry */ -BM_Entry* -BM_NewHeader(const char* name) -{ - BM_Entry* header; - header = bm_NewEntry(BM_TYPE_HEADER); - if (!header) return NULL; - StrAllocCopy(header->name, name); - return header; -} - -/* creates a new URL bookmarks entry */ -BM_Entry* -BM_NewUrl(const char* name, const char* address, const char* content_type, - BM_Date last_visit) -{ - BM_Entry* url; - - url = bm_NewEntry(BM_TYPE_URL); - - if (!url) return NULL; - - StrAllocCopy(url->name, name); - url->description = NULL; - StrAllocCopy(url->d.url.address, address); - StrAllocCopy(url->d.url.content_type, content_type); - url->d.url.last_visit = last_visit; - url->d.url.last_modified = last_visit; /* ### Is this right? */ - url->addition_date = 0; - - return url; -} - -/* creates a new URL bookmarks entry */ -static BM_Entry* -bm_NewAddress(const char* name, const char* address) -{ - BM_Entry* add_struct; - - add_struct = bm_NewEntry(BM_TYPE_ADDRESS); - - if (!add_struct) return NULL; - - StrAllocCopy(add_struct->name, name ? name : ""); - StrAllocCopy(add_struct->d.address.address, address ? address : ""); - - return add_struct; -} - -/* creates a new separator bookmarks entry */ -static BM_Entry* -bm_NewSeparator(void) -{ - return bm_NewEntry(BM_TYPE_SEPARATOR); -} - -/* creates a new alias bookmarks entry */ -static BM_Entry* -bm_NewAlias(BM_Entry* original) -{ - BM_Entry* alias; - alias = bm_NewEntry(BM_TYPE_ALIAS); - alias->d.alias.original = original; - BM_SETFLAG(original, BM_ATTR_HASALIASES); - return alias; -} - -extern BM_Entry* BM_CopyBookmark(MWContext* context, BM_Entry* original) -{ - BM_Entry* copy; - BM_Entry* child; - BM_Entry* childCopy; - - copy = NULL; - - if(!original) - return NULL; - - switch (original->type) { - case BM_TYPE_URL: - copy = BM_NewUrl(original->name, original->d.url.address, - original->d.url.content_type, original->d.url.last_visit); - break; - case BM_TYPE_ADDRESS: - copy = bm_NewAddress(original->name, original->d.address.address); - break; - case BM_TYPE_SEPARATOR: - copy = bm_NewSeparator(); - break; - case BM_TYPE_ALIAS: - copy = bm_NewAlias(original->d.alias.original); - break; - case BM_TYPE_HEADER: - copy = BM_NewHeader(original->name); - - child = original->d.header.children; - - while (child) { - childCopy = BM_CopyBookmark(context, child); - if(childCopy) - BM_AppendToHeader(context, copy, childCopy); - child = child->next; - } - break; - } - - if(copy) - { - StrAllocCopy(copy->description, original->description); - StrAllocCopy(copy->nickname, original->nickname); - } - return copy; -} - -/* gets the top node of the bmlist */ -BM_Entry* -BM_GetRoot(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXT(context); - if (!f) return NULL; - if (!f->gBookmarks) { - f->gBookmarks = BM_NewHeader(context->type == MWContextBookmarks ? - XP_GetString(XP_BKMKS_HEADER) : XP_GetString(XP_ADDRBOOK_HEADER)); - if (context->type == MWContextBookmarks) { - f->menuheader = f->addheader = f->gBookmarks; - } - bm_SyncCount(context); - } else { - if (f->gBookmarks->parent != NULL) - XP_ASSERT(f->gBookmarks->next == NULL); /* Stupid consistancy test; - dunno what action to take if - this isn't so. */ - } - return f->gBookmarks; -} - -static void -bm_EachEntryDo_1(MWContext* context, BM_Entry* at, EntryFunc func, void* closure) -{ - BM_Entry* nextChild; - BM_Entry* children; - - while (at) { - nextChild = at->next; - if (BM_ISHEADER(at)) { - children = at->d.header.children; - } else { - children = NULL; - } - - (*func)(context, at, closure); - - if (children) { - bm_EachEntryDo_1(context, children, func, closure); - } - - at = nextChild; - } -} - -static void -bm_EachSelectedEntryDo_1(MWContext* context, BM_Entry* at, EntryFunc func, - void* closure) -{ - BM_Entry* nextChild; - BM_Entry* children; - - while (at) { - nextChild = at->next; - if (BM_ISHEADER(at)) { - children = at->d.header.children; - } else { - children = NULL; - } - - if (BM_ISSELECTED(at)) (*func)(context, at, closure); - - if (children) { - bm_EachSelectedEntryDo_1(context, children, func, closure); - } - - at = nextChild; - } -} - -static void -bm_EachProperSelectedEntryDo_1(MWContext* context, BM_Entry* at, EntryFunc func, - void* closure, struct BM_Entry_Focus* bmFocus) -{ - BM_Entry* child; - BM_Entry* nextChild; - - XP_ASSERT(at); - if (!at) return; - - XP_ASSERT(BM_ISHEADER(at)); - child = at->d.header.children; - - while (child) { - nextChild = child->next; - switch (child->type) { - case BM_TYPE_URL: - case BM_TYPE_ADDRESS: - case BM_TYPE_SEPARATOR: - case BM_TYPE_ALIAS: - if (BM_ISSELECTED(child)) { - if ((bmFocus != NULL) && !bmFocus->foundSelection) - bmFocus->foundSelection = TRUE; - (*func)(context, child, closure); - } - else if (bmFocus && !bmFocus->foundSelection) { - bmFocus->saveFocus = child; - } - break; - case BM_TYPE_HEADER: - if (BM_ISSELECTED(child)) { - if ((bmFocus != NULL) && !bmFocus->foundSelection) - bmFocus->foundSelection = TRUE; - (*func)(context, child, closure); - } - else { - if (bmFocus && !bmFocus->foundSelection) - bmFocus->saveFocus = child; - if (! BM_ISFOLDED(child)) { - bm_EachProperSelectedEntryDo_1(context, child, func, closure, bmFocus); - } - } - break; - } - child = nextChild; - } -} - - - -void -BM_EachEntryDo(MWContext* context, EntryFunc func, void* closure) -{ - CHKCONTEXTVOID(context); - bm_EachEntryDo_1(context, BM_GetRoot(context), func, closure); -} - -void -BM_EachSelectedEntryDo(MWContext* context, EntryFunc func, void* closure) -{ - CHKCONTEXTVOID(context); - bm_EachSelectedEntryDo_1(context, BM_GetRoot(context), func, closure); -} - -void -BM_EachProperSelectedEntryDo(MWContext* context, EntryFunc func, void* closure, - struct BM_Entry_Focus* bmFocus) -{ - CHKCONTEXTVOID(context); - bm_EachProperSelectedEntryDo_1(context, BM_GetRoot(context), func, closure, - bmFocus); -} - - - -static void -bm_ClearMarkEverywhere_1(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_CLEARFLAG(entry, BM_ATTR_MARKED); -} - - -static void -bm_ClearMarkEverywhere(MWContext* context) -{ - BM_EachEntryDo(context, bm_ClearMarkEverywhere_1, NULL); -} - - -static MWContext* -bm_GetContextForEntry(BM_Entry* entry) -{ - MWContext* result; - BM_Frame* f; - while (entry->parent) entry = entry->parent; - for (result = ContextList ; result ; result = f->next) { - f = GETFRAME(result); - if (f->gBookmarks == entry) return result; - } - return NULL; -} - - -BM_Type -BM_GetType(BM_Entry* entry) -{ - XP_ASSERT(entry); - return entry ? entry->type : 0; -} - - -/* return the "name" for item -- may vary depending on its type */ -char* -BM_GetName(BM_Entry* entry) -{ - XP_ASSERT(entry); - if (!entry) return NULL; - - switch (entry->type) { - case BM_TYPE_URL: - case BM_TYPE_HEADER: - case BM_TYPE_ADDRESS: - return entry->name; - case BM_TYPE_ALIAS: - if (entry->d.alias.original) - return BM_GetName(entry->d.alias.original); - else - return entry->name; - default: - return NULL; - } -} - -/* return the "address" for item -- may vary depending - on its type */ -char* -BM_GetAddress(BM_Entry* entry) -{ - XP_ASSERT(entry); - if (!entry) return NULL; - - switch (entry->type) { - case BM_TYPE_URL: - return entry->d.url.address; - case BM_TYPE_ADDRESS: - return entry->d.address.address; - case BM_TYPE_HEADER: - case BM_TYPE_SEPARATOR: - case BM_TYPE_ALIAS: - if (entry->d.alias.original) return BM_GetAddress(entry->d.alias.original); - return NULL; - default: - return NULL; - } -} - -/* return the "target" for item -- may vary depending - on its type */ -char* -BM_GetTarget(BM_Entry* entry, XP_Bool recurse) -{ - XP_ASSERT(entry); - if (!entry) return NULL; - - switch (entry->type) { - case BM_TYPE_URL: - if ((recurse)&&(entry->d.url.target == NULL)&&(entry->parent != NULL)) - { - return BM_GetTarget(entry->parent, recurse); - } - else - { - return entry->d.url.target; - } - case BM_TYPE_HEADER: - if ((recurse)&&(entry->d.header.target == NULL)&&(entry->parent != NULL)) - { - return BM_GetTarget(entry->parent, recurse); - } - else - { - return entry->d.header.target; - } - case BM_TYPE_ADDRESS: - case BM_TYPE_SEPARATOR: - return NULL; - case BM_TYPE_ALIAS: - if (entry->d.alias.original) return BM_GetTarget(entry->d.alias.original, recurse); - return NULL; - default: - return NULL; - } -} - -/* return the "description" for item -- may vary depending on its type */ -char* -BM_GetDescription(BM_Entry* entry) -{ - XP_ASSERT(entry); - if (!entry) return NULL; - - switch (entry->type) { - case BM_TYPE_URL: - case BM_TYPE_HEADER: - case BM_TYPE_ADDRESS: - return entry->description; - default: - return NULL; - } -} - -char* -BM_GetNickName(BM_Entry* entry) -{ - XP_ASSERT(bm_GetContextForEntry(entry)->type == MWContextAddressBook); - if (BM_ISALIAS(entry)) return BM_GetNickName(entry->d.alias.original); - else return entry->nickname; -} - - -PRIVATE int32 -bm_CountAliases_1(BM_Entry* at, BM_Entry* forEntry) -{ - int32 count = 0; - for ( ; at ; at = at->next) { - if (BM_ISHEADER(at)) { - count += bm_CountAliases_1(at->d.header.children, forEntry); - } else if (BM_ISALIAS(at)) { - if (at->d.alias.original == forEntry) count++; - } - } - return count; -} - -PUBLIC int32 -BM_CountAliases(MWContext* context, BM_Entry* entry) -{ - int32 result; - CHKCONTEXT(context); - result = bm_CountAliases_1(BM_GetRoot(context), entry); - if (result) { - XP_ASSERT(entry->flags & BM_ATTR_HASALIASES); - BM_SETFLAG(entry, BM_ATTR_HASALIASES); - } else { - BM_CLEARFLAG(entry, BM_ATTR_HASALIASES); - } - return result; -} - -BM_Date -BM_GetLastVisited(BM_Entry *entry) -{ - XP_ASSERT(entry); - if (!entry || (entry->type != BM_TYPE_URL)) return 0; - - return entry->d.url.last_visit; -} - -BM_Date -BM_GetAdditionDate(BM_Entry *entry) -{ - XP_ASSERT(entry); - - if (!entry) return 0; - - return entry->addition_date; -} - - -/* pretty print the last visited date ### fix i18n */ -char* -BM_PrettyLastVisitedDate(BM_Entry* entry) -{ - static char buffer[200]; - - buffer[0] = 0; - - XP_ASSERT(entry); - if (!entry) return NULL; - - if (entry->type == BM_TYPE_URL) { - time_t lastVisited; - time_t today; - time_t elapsed; - - lastVisited = entry->d.url.last_visit; - if (lastVisited == 0) return ""; - today = XP_TIME(); - - elapsed = today - lastVisited; - - if (elapsed < SECONDS_PER_DAY) { - int32 hours = (elapsed + 1800L) / 3600L; - if (hours < 1) { - return XP_GetString(XP_BKMKS_LESS_THAN_ONE_HOUR_AGO); - } - sprintf(buffer, XP_GetString(XP_BKMKS_HOURS_AGO), hours); - } else if (elapsed < (SECONDS_PER_DAY * 31)) { - sprintf(buffer, XP_GetString(XP_BKMKS_DAYS_AGO), - (elapsed + (SECONDS_PER_DAY / 2)) / SECONDS_PER_DAY); - } else { - struct tm* tmp; - tmp = localtime(&lastVisited); - - sprintf(buffer, asctime(tmp)); - } - return buffer; - } - return NULL; -} - -/* pretty print the added on date */ -char* -BM_PrettyAddedOnDate(BM_Entry* entry) -{ - static char buffer[200]; - struct tm* tmp; - - XP_ASSERT(entry); - - if (entry && entry->addition_date != 0) { - tmp = localtime(&(entry->addition_date)); - sprintf(buffer, asctime(tmp)); - return buffer; - } - return NULL; -} - -char* -BM_PrettyAliasCount(MWContext* context, BM_Entry* entry) -{ - static char buffer[100]; - int32 count; - char* name = context->type == MWContextBookmarks ? - XP_GetString(XP_BKMKS_BOOKMARK) : XP_GetString(XP_BKMKS_ENTRY); - CHKCONTEXT(context); - XP_ASSERT(entry); - if (!entry) return NULL; - - count = BM_CountAliases(context, entry); - buffer[0] = 0; - - if (count > 1) { - sprintf(buffer, XP_GetString(XP_BKMKS_COUNTALIASES_MANY), count, name); - } else if (count == 1) { - sprintf(buffer, XP_GetString(XP_BKMKS_COUNTALIASES_ONE), name); - } else { - sprintf(buffer, XP_GetString(XP_BKMKS_COUNTALIASES_NONE), name); - } - return buffer; -} - - -BM_Entry* -BM_GetChildren(BM_Entry* entry) -{ - if (BM_ISHEADER(entry)) return entry->d.header.children; - return NULL; -} - -BM_Entry* -BM_GetNext(BM_Entry* entry) -{ - XP_ASSERT(entry); - return entry ? entry->next : NULL; -} - - -BM_Entry* -BM_GetParent(BM_Entry* entry) -{ - XP_ASSERT(entry); - return entry ? entry->parent : NULL; -} - - -XP_Bool -BM_HasNext(BM_Entry* entry) -{ - XP_ASSERT(entry); - return entry ? (entry->next != NULL) : FALSE; -} - - -XP_Bool -BM_HasPrev(BM_Entry* entry) -{ - BM_Entry* parent = entry->parent; - if (parent) { - XP_ASSERT(BM_ISHEADER(parent)); - return parent->d.header.children != entry; - } else { - return GETFRAME(bm_GetContextForEntry(entry))->gBookmarks != entry; - } -} - - -static void -bm_flush_updates(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - if (f->first_update_line > 0) { - BMFE_RefreshCells(context, f->first_update_line, f->last_update_line, - FALSE); - f->first_update_line = 0; - } -} - -static void -bm_start_batch(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - -#ifdef XP_UNIX - BMFE_StartBatch(context); -#endif - - CHKCONTEXTVOID(context); - if (f->undo) UNDO_StartBatch(f->undo); - f->batch_depth++; -} - -static void -bm_end_batch(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - f->batch_depth--; - XP_ASSERT(f->batch_depth >= 0); - if (f->batch_depth == 0) { - bm_flush_updates(context); - } - if (f->undo) UNDO_EndBatch(f->undo, NULL, NULL); - -#ifdef XP_UNIX - BMFE_EndBatch(context); -#endif -} - -static void -bm_refresh(MWContext* context, int32 first, int32 last) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - XP_ASSERT(first >= 1 && first <= last); - if (first < 1 || first > last) { - /* Something bogus got passed in; just repaint everything to - be safe. */ - first = 1; - last = BM_LAST_CELL; - } - if (f->first_update_line <= 0 || - first > f->last_update_line + 1 || - last + 1 < f->first_update_line) { - bm_flush_updates(context); - f->first_update_line = first; - f->last_update_line = last; - } else { - if (f->first_update_line > first) f->first_update_line = first; - if (f->last_update_line < last) f->last_update_line = last; - } - if (f->batch_depth == 0) bm_flush_updates(context); -} - - -/* Handy routine to detect if we're already going to refresh everything. - If so, then the caller knows there's no need to refresh any more... */ -static XP_Bool -bm_refreshing_all(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - return (f != NULL && - f->first_update_line == 1 && - f->last_update_line == BM_LAST_CELL); -} - - -static void -bm_entry_changed_2(MWContext* context, BM_Entry* entry) -{ - int32 index = BM_GetIndex(context, entry); - if (index < 1) return; - if (context->type == MWContextBookmarks || entry->parent == NULL) { - bm_refresh(context, index, index); - } else { - /* Changing the entry might have messed up the sorting order. Better - go resort it. What a hack...*/ - BM_Entry* parent = entry->parent; - BM_RemoveChildFromHeader(context, parent, entry); - bm_AddChildToHeaderSorted(context, parent, entry); - } -} - -static void -bm_entry_changed_1(MWContext* context, BM_Entry* entry, BM_Entry* find) -{ - for (; entry ; entry = entry->next) { - if (BM_ISALIAS(entry) && entry->d.alias.original == find) { - bm_entry_changed_2(context, entry); - } else if (BM_ISHEADER(entry)) { - bm_entry_changed_1(context, entry->d.header.children, find); - } - } -} - -static void -bm_entry_changed(MWContext* context, BM_Entry* entry) -{ - XP_ASSERT(!BM_ISALIAS(entry)); - if (entry->flags & BM_ATTR_HASALIASES) { - bm_entry_changed_1(context, BM_GetRoot(context), entry); - } - bm_entry_changed_2(context, entry); -} - - -static void -bm_save_timer(void* closure) -{ - MWContext* context = (MWContext*) closure; - BM_Frame* f = GETFRAME(context); - f->savetimer = NULL; - BM_SaveBookmarks(context, NULL); -} - -/* The bookmarks have been modified somehow. Set or reset a timer to cause - them to be saved.*/ -static void -bm_SetModified(MWContext* context, XP_Bool mod) -{ - BM_Frame* f = GETFRAME(context); - f->gBookmarksModified = mod; - f->max_depth = 0; - if (f->savetimer) { - FE_ClearTimeout(f->savetimer); - f->savetimer = NULL; - } - if (mod) { - f->savetimer = FE_SetTimeout(bm_save_timer, context, - 60000L); /* ### hard-coding... */ - if (!f->savetimer) BM_SaveBookmarks(context, NULL); - } -} - -/* give LI the ability to set the modified to false */ -void -BM_SetModified(MWContext* context, XP_Bool mod) -{ - bm_SetModified(context, mod); -} - -typedef struct bm_setheader_info { - MWContext* context; - BM_Entry* entry; - XP_Bool isadd; -} bm_setheader_info; - -static void -bm_setheader_freeit(void* closure) -{ - XP_FREE((bm_setheader_info*) closure); -} - -static int bm_setheader_undo(void* closure); - -static void -bm_SetMenuOrAddHeader(MWContext* context, BM_Entry* entry, XP_Bool isadd) -{ - BM_Frame* f = GETFRAME(context); - XP_ASSERT(context->type == MWContextBookmarks); - XP_ASSERT(BM_ISHEADER(entry)); - if (context->type == MWContextBookmarks && f && BM_ISHEADER(entry)) { - if (f->undo) { - bm_setheader_info* info = XP_NEW_ZAP(bm_setheader_info); - if (!info) { - UNDO_DiscardAll(f->undo); - } else { - info->context = context; - info->entry = isadd ? f->addheader : f->menuheader; - info->isadd = isadd; - UNDO_LogEvent(f->undo, bm_setheader_undo, bm_setheader_freeit, info, NULL, NULL); - } - } - bm_start_batch(context); - bm_entry_changed(context, isadd ? f->addheader : f->menuheader); - if (isadd) f->addheader = entry; - else f->menuheader = entry; - bm_entry_changed(context, entry); - if (!isadd) BMFE_BookmarkMenuInvalid(context); - bm_SetModified(context, TRUE); - bm_end_batch(context); - } -} - -int bm_setheader_undo(void* closure) -{ - bm_setheader_info* info = (bm_setheader_info*) closure; - bm_SetMenuOrAddHeader(info->context, info->entry, info->isadd); - return 0; -} - -BM_Entry* -BM_GetMenuHeader(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - XP_ASSERT(context->type == MWContextBookmarks); - return f ? f->menuheader : NULL; -} - -void BM_SetMenuHeader(MWContext* context, BM_Entry* entry) -{ - bm_SetMenuOrAddHeader(context, entry, FALSE); -} - - -BM_Entry* -BM_GetAddHeader(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - XP_ASSERT(context->type == MWContextBookmarks); - return f ? f->addheader : NULL; -} - -void BM_SetAddHeader(MWContext* context, BM_Entry* entry) -{ - bm_SetMenuOrAddHeader(context, entry, TRUE); -} - - -typedef struct bm_copy_string_info { - MWContext* context; - BM_Entry* entry; - char** string; - char* value; -} bm_copy_string_info; - - -static void -bm_copy_string_freeit(void* closure) -{ - bm_copy_string_info* info = (bm_copy_string_info*) closure; - FREEIF(info->value); - XP_FREE(info); -} - -static int bm_copy_string_undo(void* closure); - -static int -bm_CopyStringWithUndo(MWContext* context, BM_Entry* entry, char** string, - const char* value) -{ - BM_Frame* f = GETFRAME(context); - int status = 0; - bm_SetModified(context, TRUE); - if (f->undo) { - bm_copy_string_info* info = XP_NEW_ZAP(bm_copy_string_info); - if (!info) { - UNDO_DiscardAll(f->undo); - status = MK_OUT_OF_MEMORY; - } else { - info->context = context; - info->entry = entry; - info->string = string; - info->value = *string ? XP_STRDUP(*string) : NULL; - UNDO_LogEvent(f->undo, bm_copy_string_undo, bm_copy_string_freeit, - info, NULL, NULL); - } - } - if (*string) XP_FREE(*string); - *string = value ? XP_STRDUP(value) : NULL; - bm_entry_changed(context, entry); - return 0; -} - -static int -bm_copy_string_undo(void* closure) -{ - bm_copy_string_info* info = (bm_copy_string_info*) closure; - if (info->string == &(info->entry->nickname)) { - /* Have to use BM_SetNickName to get side effect of changing hashtable. */ - BM_SetNickName(info->context, info->entry, info->value); - } else { - bm_CopyStringWithUndo(info->context, info->entry, info->string, - info->value); - } - return 0; -} - - - -/* sets the name for a bm entry */ -void -BM_SetName(MWContext* context, BM_Entry* entry, const char* newName) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(entry); - if (!entry) return; - BM_CLEARFLAG(entry, BM_ATTR_ISNEW); - - switch (entry->type) { - case BM_TYPE_URL: - case BM_TYPE_HEADER: - case BM_TYPE_ADDRESS: - if (entry->name == NULL || XP_STRCMP(entry->name, newName) != 0) { - bm_CopyStringWithUndo(context, entry, &entry->name, newName); - BMFE_BookmarkMenuInvalid(context); - } - break; - case BM_TYPE_ALIAS: - BM_SetName(context, entry->d.alias.original, newName); - break; - } -} - - - -/* sets the location field of a bm_url bookmarks entry */ -void -BM_SetAddress(MWContext* context, BM_Entry* entry, const char* newAddress) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(entry); - if (!entry) return; - BM_CLEARFLAG(entry, BM_ATTR_ISNEW); - - switch (entry->type) { - case BM_TYPE_URL: - if (entry->d.url.address == NULL || - XP_STRCMP(entry->d.url.address, newAddress) != 0) { - bm_CopyStringWithUndo(context, entry, &entry->d.url.address, newAddress); - } - break; - case BM_TYPE_ADDRESS: - if (entry->d.address.address == NULL || - XP_STRCMP(entry->d.address.address, newAddress) != 0) { - bm_CopyStringWithUndo(context, entry, &entry->d.address.address, - newAddress); - } - break; - case BM_TYPE_ALIAS: - BM_SetAddress(context, entry->d.alias.original, newAddress); - break; - } -} - - -/* sets the target field of a bm_url bookmarks entry */ -void -BM_SetTarget(MWContext* context, BM_Entry* entry, const char* newTarget) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(entry); - if (!entry) return; - BM_CLEARFLAG(entry, BM_ATTR_ISNEW); - - switch (entry->type) { - case BM_TYPE_URL: - if (entry->d.url.target == NULL || - XP_STRCMP(entry->d.url.target, newTarget) != 0) { - bm_CopyStringWithUndo(context, entry, &entry->d.url.target, newTarget); - if (entry->d.url.target[0] == '\0') { - entry->d.url.target = NULL; - } - } - break; - case BM_TYPE_HEADER: - if (entry->d.header.target == NULL || - XP_STRCMP(entry->d.header.target, newTarget) != 0) { - bm_CopyStringWithUndo(context, entry, &entry->d.header.target, newTarget); - if (entry->d.header.target[0] == '\0') { - entry->d.header.target = NULL; - } - } - break; - case BM_TYPE_ADDRESS: - break; - case BM_TYPE_ALIAS: - BM_SetAddress(context, entry->d.alias.original, newTarget); - break; - } -} - -/* sets the description field of an entry */ -PUBLIC void -BM_SetDescription(MWContext* context, BM_Entry* entry, const char* newDesc) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(entry); - if (!entry) return; - BM_CLEARFLAG(entry, BM_ATTR_ISNEW); - - switch (entry->type) { - case BM_TYPE_URL: - case BM_TYPE_HEADER: - case BM_TYPE_ADDRESS: - if (entry->description == NULL || - XP_STRCMP(entry->description, newDesc)) { - bm_CopyStringWithUndo(context, entry, &entry->description, newDesc); - } - break; - case BM_TYPE_ALIAS: - BM_SetDescription(context, entry->d.alias.original, newDesc); - break; - } -} - - -/* BM_SetNickName returns FALSE if it reported an error to the user . - * It returns TRUE if everything worked fine. - * 5-16-95 jefft - * Passing in NULL value removes the entry from the hash table. - */ - -XP_Bool -BM_SetNickName(MWContext* context, BM_Entry* entry, const char* value) -{ - BM_Frame* f = GETFRAME(context); - char* pName; - CHKCONTEXT(context); - XP_ASSERT(context->type == MWContextAddressBook); - if (!entry) return(TRUE); - if (!value) { - /* 5-16-95 jefft -- bug#: 20808, remove entry from the hash table */ - if (entry->nickname && *entry->nickname) { - XP_Remhash(f->nicknameTable, entry->nickname); - FREEIF(entry->nickname); - } - return(TRUE); - } - - /* allocate a copy of the string so we can modify it to be a legal alias */ - /* But only if value is non-null */ - pName = (value) ? XP_STRDUP(value) : NULL; - if (value && !pName) return(FALSE); - - BM_CLEARFLAG(entry, BM_ATTR_ISNEW); - - if (BM_ISALIAS(entry)) { - XP_Bool retVal; - retVal = BM_SetNickName(context, entry->d.alias.original, value); - XP_FREE(pName); - return(retVal); - } else { - if (entry->nickname == NULL || value == NULL || XP_STRCMP(entry->nickname, value)) { - if (pName != NULL) - { - char* ptr; - for (ptr = pName ; *ptr ; ptr++) { - if (!isalnum(*ptr) && (*ptr != '-') && (*ptr != '_')) { - FE_Alert(context, XP_GetString(XP_BKMKS_INVALID_NICKNAME)); - XP_FREE(pName); - return(FALSE); - } - /* convert to lowercase */ - if (isupper(*ptr)) { - *ptr = (char)tolower(*ptr); - } - } - if (XP_Gethash(f->nicknameTable, pName, NULL)) { - FE_Alert(context, XP_GetString(XP_BKMKS_NICKNAME_ALREADY_EXISTS)); - FREEIF(pName); - return(FALSE); - } - } - } - if (entry->nickname && *entry->nickname) { - XP_Remhash(f->nicknameTable, entry->nickname); - } - bm_CopyStringWithUndo(context, entry, &entry->nickname, pName); - if (entry->nickname && *entry->nickname) { - XP_Puthash(f->nicknameTable, entry->nickname, entry); - } - } - FREEIF(pName); - return(TRUE); -} - - - -void -BM_CancelEdit(MWContext* context, BM_Entry* entry) -{ - CHKCONTEXTVOID(context); - bm_start_batch(context); - if (entry && (entry->flags & BM_ATTR_ISNEW) && - !(entry->flags & BM_ATTR_HASALIASES) && entry->parent) { - BM_RemoveChildFromHeader(context, entry->parent, entry); - BM_FreeEntry(context, entry); - bm_refresh(context, 1, BM_LAST_CELL); - } - bm_end_batch(context); -} - - - -/* returns the number of children parent has - if visible is TRUE, only visible children are counted, - otherwise all children are counted */ -static int32 -bm_CountChildren(BM_Entry* parent, XP_Bool visible) -{ - BM_Entry* child; - int32 count = 1; - - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - - if (!parent || !BM_ISHEADER(parent)) return 0; - - if (!visible || !(parent->flags & BM_ATTR_FOLDED)) { - child = parent->d.header.children; - while (child) { - if (BM_ISHEADER(child)) { - count += bm_CountChildren(child, visible); - } else { - count++; - } - child = child->next; - } - } - - return count; -} - - -static void -bm_WidestEntry_1(MWContext* context, BM_Entry* parent, BM_Entry** widest, - uint32* widestWidth) -{ - BM_Entry* child; - uint32 width; - uint32 height; - - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - XP_ASSERT(widestWidth); - XP_ASSERT(widest); - - BMFE_MeasureEntry(context, parent, &width, &height); - - if (width > *widestWidth) { - *widestWidth = width; - *widest = parent; - } - - if (!(BM_ISFOLDED(parent))) { - child = parent->d.header.children; - while (child) { - if (BM_ISHEADER(child)) { - bm_WidestEntry_1(context, child, widest, widestWidth); - } else { - BMFE_MeasureEntry(context, child, &width, &height); - if (width > *widestWidth) { - *widestWidth = width; - *widest = child; - } - } - child = child->next; - } - } -} - -/* returns the widest visible entry in the tree -(this uses a FE function to measure the width) */ -PUBLIC BM_Entry* -BM_WidestEntry(MWContext* context) -{ - BM_Entry* widest = NULL; - uint32 widestWidth = 0; - CHKCONTEXT(context); - - bm_WidestEntry_1(context, BM_GetRoot(context), &widest, &widestWidth); - return widest; -} - - -static void -bm_SyncCount(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - if (f) { - f->gCount = -1; - f->gVisCount = -1; - } - BMFE_SyncDisplay(context); -} - -PRIVATE void -bm_SyncSelection_1(BM_Entry* parent, int32* count, uint32* selectionMask) -{ - BM_Entry* child; - - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - - if (parent->flags & BM_ATTR_SELECTED) { - *selectionMask |= BM_TYPE_HEADER; - (*count)++; - } - - child = parent->d.header.children; - while (child) { - if (BM_ISHEADER(child)) { - bm_SyncSelection_1(child, count, selectionMask); - } else { - if (BM_ISSELECTED(child)) { - *selectionMask |= child->type; - (*count)++; - } - } - child = child->next; - } -} - -/* synchronizes the selection mask and the selection count with - what is actually selected - this is necessary when items become deselected because - we don't have a global selection list, only a count and - mask -*/ -static void -bm_SyncSelection(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - f->gSelectionCount = 0; - f->gSelectionMask = 0; - - bm_SyncSelection_1(BM_GetRoot(context), &(f->gSelectionCount), - &(f->gSelectionMask)); -} - -/* return the index number of item in cur_count with regards -to the BM_ATTR_FOLDED flag */ -PRIVATE int32 -bm_GetIndexNum(BM_Entry* parent, BM_Entry* item, int32* cur_count) -{ - BM_Entry* child; - int32 rv = 0; - - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - - child = parent->d.header.children; - - if (parent == item) return *cur_count; - - while (child) { - (*cur_count)++; - - if (child == item) { - return *cur_count; - } - - /* if it's a header and it's unfolded, traverse it's children */ - if (child->type == BM_TYPE_HEADER && !BM_ISFOLDED(child)) { - rv = bm_GetIndexNum(child, item, cur_count); - if (rv) - return rv; - } - child = child->next; - } - return 0; -} - -/* return the index number of item in cur_count without regards to - the BM_ATTR_FOLDED flag */ -PRIVATE int32 -bm_GetUnfoldedIndexNum(BM_Entry* parent, BM_Entry* item, int32* cur_count) -{ - BM_Entry* child; - int32 rv = 0; - - XP_ASSERT(parent); - XP_ASSERT(parent->type == BM_TYPE_HEADER); - - if (parent == item) return *cur_count; - - for (child = parent->d.header.children; child; child = child->next) { - (*cur_count)++; - - if (child == item) return *cur_count; - - - if (child->type == BM_TYPE_HEADER) { - rv = bm_GetUnfoldedIndexNum(child, item, cur_count); - if (rv) return rv; - } - } - return 0; -} - -/* returns the child url entry of parent whose address is the same as - url_address */ -PRIVATE void -bm_FindItemStub(MWContext *context, BM_Entry* parent, char* url_address, EntryFunc pf, void *pClosure) -{ - BM_Entry* child; - - if (!parent) { /* Eric made me do it */ - return; - } - - for (child = parent->d.header.children; child; child = child->next) { - if (child->type == BM_TYPE_URL && child->d.url.address && - !XP_STRCMP(child->d.url.address, url_address)) { - (*pf)(context, child, pClosure); - } - if (child->type == BM_TYPE_HEADER) { - bm_FindItemStub(context, child, url_address, pf, pClosure); - } - } - return; -} - - -PRIVATE int32 -bm_GetDepth(BM_Entry* parent, BM_Entry* item) -{ - int32 rv = 0; - BM_Entry* next; - - if (!item) return -1; - - next = item; - while (next && next->parent) { /* I think extra "next &&" is - necessary for Win16 busted - optimizer... */ - rv++; - next = next->parent; - } - return rv; -} - - - -static void -bm_simple_freeit(void* closure) -{ - XP_FREE(closure); -} - - -typedef struct bm_delete_child_info { - MWContext* context; - BM_Entry* parent; - BM_Entry* child; -} bm_delete_child_info; - - -static int -bm_delete_child_doit(void* closure) -{ - bm_delete_child_info* info = (bm_delete_child_info*) closure; - BM_RemoveChildFromHeader(info->context, info->parent, info->child); - return 0; -} - - -static void -bm_LogDeleteChild(MWContext* context, BM_Entry* parent, BM_Entry* child) -{ - BM_Frame* f = GETFRAME(context); - bm_delete_child_info* info; - - /* Magic side effect -- if a child has just been added, and it doesn't have - an addition date set, set it to be now. */ - if (child->addition_date == 0) { - child->addition_date = XP_TIME(); - } - - if (!f || !f->undo) return; - bm_SetModified(context, TRUE); - info = XP_NEW_ZAP(bm_delete_child_info); - if (!info) { - UNDO_DiscardAll(f->undo); - } else { - info->context = context; - info->parent = parent; - info->child = child; - UNDO_LogEvent(f->undo, bm_delete_child_doit, bm_simple_freeit, info, NULL, NULL); - } -} - -/* appends a child item to a parent at the end of the - parents child list */ -static void -bm_AppendChildToHeader(MWContext* context, BM_Entry* parent, BM_Entry* child) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* lastChild; - - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - XP_ASSERT(child); - XP_ASSERT(child != parent); - - f->gCount = -1; - f->gVisCount = -1; - - lastChild = parent->d.header.lastChild; - if (lastChild) { - lastChild->next = child; - parent->d.header.lastChild = child; - } else { - parent->d.header.children = child; - parent->d.header.lastChild = child; - } - - parent->d.header.childCount++; - child->parent = parent; - - if( !f->bSorting ) - child->iNaturalIndex = g_iNaturalIndexPool++; - - if (context) { - BMFE_BookmarkMenuInvalid(context); - bm_LogDeleteChild(context, parent, child); - } -} - -void -BM_AppendToHeader(MWContext* context, BM_Entry* parent, BM_Entry* child) -{ - int index; - bm_start_batch(context); - bm_AppendChildToHeader(context, parent, child); - index = BM_GetIndex(context, child); - if (index > 0) bm_refresh(context, index, BM_LAST_CELL); - bm_end_batch(context); -} - - -/* Add a child item to a parent at the beginning of the - parents child list */ -void -BM_PrependChildToHeader(MWContext* context, BM_Entry* parent, BM_Entry* child) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* firstChild; - - XP_ASSERT(parent); - XP_ASSERT(parent->type == BM_TYPE_HEADER); - XP_ASSERT(child); - XP_ASSERT(child != parent); - - f->gCount = -1; - f->gVisCount = -1; - firstChild = parent->d.header.children; - if (!firstChild) { - bm_AppendChildToHeader(context, parent, child); - } else { - child->next = firstChild; - parent->d.header.children = child; - - parent->d.header.childCount++; - child->parent = parent; - - if( !f->bSorting ) - child->iNaturalIndex = g_iNaturalIndexPool++; - - if (context) { - BMFE_BookmarkMenuInvalid(context); - bm_LogDeleteChild(context, parent, child); - } - } -} - - -static int -bm_SortAddressBook(const void* obj1, const void* obj2) -{ - const BM_Entry* entry1 = (const BM_Entry*) obj1; - const BM_Entry* entry2 = (const BM_Entry*) obj2; - - if (BM_ISALIAS(entry1)) { - entry1 = entry1->d.alias.original; - XP_ASSERT(!BM_ISALIAS(entry1)); - } - if (BM_ISALIAS(entry2)) { - entry2 = entry2->d.alias.original; - XP_ASSERT(!BM_ISALIAS(entry2)); - } - XP_ASSERT(BM_ISHEADER(entry1) || BM_ISADDRESS(entry1)); - XP_ASSERT(BM_ISHEADER(entry2) || BM_ISADDRESS(entry2)); - if (entry1 == entry2) return 0; /* Can happen with two aliases to the same - thing... */ - if (BM_ISHEADER(entry1)) { - if (BM_ISHEADER(entry2)) { -#ifdef INTL_SORT - return XP_StrColl(entry1->name, entry2->name); -#else - return XP_STRCMP(entry1->name, entry2->name); -#endif - } else { - return 1; - } - } else { - if (BM_ISHEADER(entry2)) { - return -1; - } else { -#ifdef INTL_SORT - return XP_StrColl(entry1->name, entry2->name); -#else - return XP_STRCMP(entry1->name, entry2->name); -#endif - } - } -} - - -static BM_Entry* -bm_RealEntry(BM_Entry* entry) -{ - if (BM_ISALIAS(entry)) return entry->d.alias.original; - else return entry; -} - - -/* Adds a child item to a parent, sorting it according to address book sorting - rules. */ -static void -bm_AddChildToHeaderSorted(MWContext* context, BM_Entry* parent, - BM_Entry* child) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* entry; - BM_Entry* previous = NULL; - XP_ASSERT(context->type == MWContextAddressBook); - XP_ASSERT(BM_ISHEADER(parent)); - if (!BM_ISALIAS(child)) parent = BM_GetRoot(context); - if (parent->d.header.lastChild && - bm_SortAddressBook(parent->d.header.lastChild, child) < 0) { - /* Ah, the most common case (especially when loading from a file). This - kid goes last. */ - previous = parent->d.header.lastChild; - bm_AppendChildToHeader(context, parent, child); - } else { - for (entry = parent->d.header.children ; entry ; entry = entry->next) { - int value = bm_SortAddressBook(entry, child); - if (value > 0) break; - if (value == 0) { - /* Hmm. Let's not allow any duplicate aliases to the same thing - in the same header. */ - if (bm_RealEntry(entry) == bm_RealEntry(child)) { - if (BM_ISALIAS(child)) { - BM_FreeEntry(context, child); - } else { - XP_ASSERT(BM_ISALIAS(entry)); - BM_RemoveChildFromHeader(context, parent, entry); - bm_AddChildToHeaderSorted(context, parent, child); - } - return; - } - } - previous = entry; - } - if (previous == NULL) { - BM_PrependChildToHeader(context, parent, child); - previous = parent; - } else { - bm_InsertItemAfter(context, previous, child, FALSE); - } - } - f->gCount = -1; - f->gVisCount = -1; - if (!BM_ISFOLDED(parent) && !bm_refreshing_all(context)) { - int index = BM_GetIndex(context, previous); - if (index > 0) { - f->gVisCount++; - bm_refresh(context, index + 1, BM_LAST_CELL); - } - } -} - -static BM_Entry* -bm_get_previous(BM_Entry* entry) -{ - BM_Entry* child; - BM_Entry* previous = NULL; - - if (entry && entry->parent) { - child = entry->parent->d.header.children; - previous = NULL; - while (child && child != entry) { - previous = child; - child = child->next; - } - } - - if (child == NULL) previous = NULL; - - return previous; -} - - - -typedef struct bm_add_child_info { - MWContext* context; - BM_Entry* parent; - BM_Entry* previous; - BM_Entry* child; -} bm_add_child_info; - - -static int -bm_add_child_doit(void* closure) -{ - bm_add_child_info* info = (bm_add_child_info*) closure; - XP_ASSERT(info->previous == NULL || info->previous->parent == info->parent); - if (info->previous) { - bm_InsertItemAfter(info->context, info->previous, info->child, FALSE); - } else { - BM_PrependChildToHeader(info->context, info->parent, info->child); - } - BM_ClearAllSelection(info->context, FALSE); - return 0; -} - - - -void BM_RemoveChildFromHeader(MWContext* context, BM_Entry* parent, BM_Entry* child) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* previous; - - XP_ASSERT(BM_ISHEADER(parent)); - if (!BM_ISHEADER(parent)) return; - XP_ASSERT(child); - if (!child) return; - XP_ASSERT(child != parent); - if (child == parent) return; - XP_ASSERT(child->parent == parent); - if (child->parent != parent) return; - - if (context && (child->flags & BM_ATTR_SELECTED)) { - BM_SelectItem(context, child, TRUE, TRUE, FALSE); - } - previous = bm_get_previous(child); - - if (previous) previous->next = child->next; - - if (parent->d.header.children == child) { - parent->d.header.children = child->next; - } - - if (parent->d.header.lastChild == child) { - parent->d.header.lastChild = previous; - } - - f->gCount = -1; - f->gVisCount = -1; - - parent->d.header.childCount--; - - if (context) { - BM_Frame* f = GETFRAME(context); - bm_add_child_info* info; - BMFE_BookmarkMenuInvalid(context); - bm_SetModified(context, TRUE); - if (f->undo) { - info = XP_NEW_ZAP(bm_add_child_info); - if (!info) { - UNDO_DiscardAll(f->undo); - } else { - info->context = context; - info->parent = parent; - info->previous = previous; - info->child = child; - UNDO_LogEvent(f->undo, bm_add_child_doit, bm_simple_freeit, info, NULL, NULL); - } - } - } - child->parent = NULL; - child->next = NULL; -} - - - -#define BM_HEADER_BEGIN 0xD000 -#define BM_HEADER_END 0xE000 -#define BM_UNKNOWN 0xF000 - -static uint16 -bm_tokenize_line(MWContext* context, char* buffer, char** ptr) -{ - if ((*ptr = strcasestr(buffer, "HREF=\""))) { - return context->type == MWContextBookmarks ? BM_TYPE_URL : BM_TYPE_ADDRESS; - } else if ((*ptr = strcasestr(buffer, ""))) { - return BM_TYPE_SEPARATOR; - } else if (strcasestr(buffer, "") || - strcasestr(buffer, "") || - strcasestr(buffer, "")) { - return BM_HEADER_END; - } else if (strcasestr(buffer, "
    ") || - strcasestr(buffer, "") || - strcasestr(buffer, "
    ")) { - return BM_HEADER_BEGIN; - } else { - return BM_UNKNOWN; - } -} - -/* parse out the folded state in buffer */ -static XP_Bool -bm_is_folded(char* buffer) -{ - XP_ASSERT(buffer); - return strcasestr(buffer, "FOLDED") != NULL; -} - -/* parse out the addition date in buffer */ -static time_t -bm_addition_date(char* buffer) -{ - char* ptr; - char* end; - time_t add_date = 0; - - XP_ASSERT(buffer); - - ptr = strcasestr(buffer, "ADD_DATE=\""); - if (ptr) - { - /* find the end of the addition date */ - end = XP_STRCHR(ptr + 10, '"'); - if (end) - { - /* temporarily stick a NULL in the buffer */ - *end = '\0'; - - add_date = (time_t)atol(ptr + 10); - - /* replace the quote */ - *end = '"'; - } - } - return add_date; -} - -/* parse out the last visited or last modified date in buffer */ -static time_t -bm_last_date(char* buffer, XP_Bool ismodified) -{ - char* ptr; - char* start; - char* end; - time_t result = 0; - - ptr = strcasestr(buffer, - ismodified ? "LAST_MODIFIED=\"": "LAST_VISIT=\""); - if (ptr) { - start = ptr + (ismodified ? 15 : 12); - end = XP_STRCHR(start, '"'); - if (end) { - /* temporarily stick a NULL in the buffer */ - *end = '\0'; - - result = (time_t)atol(start); - - /* replace the quote */ - *end = '"'; - } - } - return result; -} - - -/* parse out the target string in buffer */ -static char * -bm_target(char* buffer, XP_Bool ismodified) -{ - char* ptr; - char* start; - char* end; - char *result = NULL; - - ptr = strcasestr(buffer, "TARGET=\""); - if (ptr) { - start = ptr + 8; - end = XP_STRCHR(start, '"'); - if (end) { - /* temporarily stick a NULL in the buffer */ - *end = '\0'; - - result = (start) ? XP_STRDUP(start) : NULL; - - /* replace the quote */ - *end = '"'; - } - } - return result; -} - - -typedef struct bm_alias_info { - char* id; /* String to use for this alias in the file. */ - char* key; /* Key to use to lookup this alias in the table */ - BM_Entry* entry; -} bm_alias_info; - - -static bm_alias_info* -bm_find_alias_info(MWContext* context, const char* ptr, XP_Bool create) -{ - BM_Frame* f = GETFRAME(context); - bm_alias_info* info = NULL; - if (f->aliasTable) { - info = (bm_alias_info *)XP_Gethash(f->aliasTable, ptr, NULL); - XP_ASSERT(info == NULL || XP_STRCMP(ptr, info->key) == 0); - if (!info && create) { - info = XP_NEW_ZAP(bm_alias_info); - if (info) { - info->key = XP_STRDUP(ptr); - XP_Puthash(f->aliasTable, info->key, info); - } - } - } - return info; -} - -static bm_alias_info* -bm_find_writealias_info(MWContext* context, BM_Entry* entry) -{ - BM_Frame* f = GETFRAME(context); - static char key[20]; - bm_alias_info* info; - XP_SPRINTF(key, "%ld", (long) entry); - info = bm_find_alias_info(context, key, TRUE); - if (info && info->id == NULL) { - info->id = (char *)XP_ALLOC(10); - if (info->id) { - XP_SPRINTF(info->id, "%d", f->aliasID++); - } - } - return info; -} - -static XP_Bool -bm_free_alias_info(XP_HashTable table, const void* key, void* value, - void* closure) -{ - bm_alias_info* info = (bm_alias_info*) value; - FREEIF(info->id); - FREEIF(info->key); - XP_FREE(info); - return TRUE; -} - - -static int -bm_string_cmp (const void *obj1, const void *obj2) -{ - XP_ASSERT (obj1 && obj2); - return XP_STRCMP((char*) obj1, (char*) obj2); -} - -static void -bm_clear_alias_info(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - if (f->aliasTable) { - XP_Maphash(f->aliasTable, bm_free_alias_info, NULL); - XP_Clrhash(f->aliasTable); - } else { - f->aliasTable = XP_HashTableNew(100, XP_StringHash, bm_string_cmp); - } - f->aliasID = 0; -} - - - -/* Checks if the given item is an alias to another item, or has aliases to it. - Takes care of all the required tree mucking, and updating of the alias - table. The return value is the item for the caller to insert into the - tree; it is usually but not always the item passed in. */ -static BM_Entry* -bm_check_read_alias(MWContext* context, BM_Entry* new_item, char* parseString) -{ - char* ptr; - char* end = NULL; - ptr = strcasestr(parseString, "ALIASID=\""); - if (ptr) { - ptr += 9; - end = XP_STRCHR(ptr, '"'); - if (end) { - bm_alias_info* info; - *end = '\0'; - info = bm_find_alias_info(context, ptr, TRUE); - if (info) { - if (info->entry) { - /* Sigh. We have the definition of an alias, but there - have already been some references to this alias, and we don't - really want to go chasing the references down. Instead, we'll - just copy our data into the existing record. Yikes. */ - BM_Entry* tmp = XP_NEW(BM_Entry); - if (tmp) { - XP_MEMCPY(tmp, info->entry, sizeof(BM_Entry)); - XP_MEMCPY(info->entry, new_item, sizeof(BM_Entry)); - BM_FreeEntry(context, tmp); - XP_FREE(new_item); - new_item = info->entry; - } - } else { - info->entry = new_item; - } - } - BM_SETFLAG(new_item, BM_ATTR_HASALIASES); - } - } else { - ptr = strcasestr(parseString, "ALIASOF=\""); - if (ptr) { - ptr += 9; - end = XP_STRCHR(ptr, '"'); - if (end) { - bm_alias_info* info; - *end = '\0'; - info = bm_find_alias_info(context, ptr, TRUE); - if (info) { - if (info->entry == NULL) { - /* Even though this entry is probably not complete, it will - do better than nothing. If something better comes along, - this one will get replaced. If not, we'll insert this - item into the main tree at the end. */ - info->entry = new_item; - } else { - BM_FreeEntry(context, new_item); - } - new_item = bm_NewAlias(info->entry); - if (!new_item) return NULL; - } - } - } - } - - /* replace the quotes */ - if (end) *end = '"'; - return new_item; -} - -static void -bm_check_nickname(MWContext* context, BM_Entry* entry, char* str) -{ - char* ptr = strcasestr(str, "NICKNAME=\""); - char* end; - if (ptr) { - ptr += 10; - end = XP_STRCHR(ptr, '"'); - if (end) { - *end = '\0'; - BM_SetNickName(context, entry, ptr); - *end = '"'; - } - } -} - -/* -// Replace all occurances of escaped quotes (%22) with explicit quotes ("). -// Do not replace beyond the end of the " delimited string. -// -// Return a ptr to the position after the last occurance of an escaped quote. -*/ -static char *bm_explicit_quotes( char *pszSource ) -{ - char *pszCsr = NULL; - char *pszLast = NULL; - - if( !pszSource ) - { - return pszSource; - } - - - pszLast = XP_STRCHR( pszSource, '"' ); - - while( (pszCsr = strstr( pszSource, "%22" )) && (pszCsr < pszLast) ) - { - *pszCsr = '"'; - pszSource = pszCsr + 1; - XP_MEMMOVE( pszSource, pszSource+2, XP_STRLEN(pszSource+2)+1 ); - } - - return pszSource; -} - - -static BM_Entry* -bm_read_url(MWContext* context, XP_File fp, char* buffer, char* ptr, - const char* relative_url) -{ - char* endQuote; - char* gtr_than; - char* parseString; - char* end; - char* url; - char *pszAfterLastEscapedQuote; - BM_Entry* new_item = NULL; - - /* find next quote */ - parseString = ptr + 6; - - /* Replace escaped quotes with explicit ones */ - pszAfterLastEscapedQuote = bm_explicit_quotes( parseString ); - - endQuote = XP_STRCHR(pszAfterLastEscapedQuote, '"'); - - if (endQuote) { - - /* temporarily terminate */ - *endQuote = '\0'; - - url = NET_MakeAbsoluteURL((char*)relative_url, parseString); - if (url) { - new_item = BM_NewUrl(NULL, url, NULL, 0); - XP_FREE(url); - } - if (!new_item) return NULL; - - /* find '>' and the name will be right after it */ - gtr_than = XP_STRCHR(endQuote + 1, '>'); - if (gtr_than) { - /* find the end of the name */ - end = strcasestr(gtr_than, ""); - if (end) { - *end = '\0'; - } else { - /* This must be a long title. - * Don't bother using the rest if it. - */ - char *dumpbuf = (char*) XP_ALLOC(READ_BUFFER_SIZE); - while (XP_FileReadLine(dumpbuf, READ_BUFFER_SIZE, fp)) { - if (strchr(dumpbuf, '\n')) - break; - } - XP_FREE(dumpbuf); - } - StrAllocCopy(new_item->name, XP_StripLine(gtr_than + 1)); - - /* terminate at beginning of name since there - is nothing interesting after that */ - *gtr_than = '\0'; - } - - parseString = endQuote + 1; - - new_item->d.url.target = bm_target(parseString, FALSE); - - new_item->addition_date = bm_addition_date(parseString); - - new_item->d.url.last_visit = bm_last_date(parseString, FALSE); - new_item->d.url.last_modified = bm_last_date(parseString, TRUE); - if (new_item->d.url.last_modified == 0) { - new_item->d.url.last_modified = new_item->d.url.last_visit; - } - - new_item = bm_check_read_alias(context, new_item, parseString); - - /* replace the quotes */ - *endQuote = '"'; - } - - return new_item; -} - - -static BM_Entry* -bm_read_address(MWContext* context, XP_File fp, char* buffer, char* ptr) -{ - char* endQuote; - char* gtr_than; - char* parseString; - char* end; - char* url; - BM_Entry* new_item = NULL; - - XP_ASSERT(context->type == MWContextAddressBook); - - /* find next quote */ - parseString = ptr + 6; - - endQuote = XP_STRCHR(parseString, '"'); - if (endQuote) { - *endQuote = '\0'; - - url = parseString; - - if (strncasecomp(url, "mailto:", 7) == 0) { - url += 7; - } - - new_item = bm_NewAddress(NULL, url); - if (!new_item) return NULL; - - /* find '>' and the name will be right after it */ - gtr_than = XP_STRCHR(endQuote + 1, '>'); - if (gtr_than) { - *gtr_than++ = '\0'; - /* find the end of the name */ - end = strcasestr(gtr_than, ""); - if (end) { - *end = '\0'; - StrAllocCopy(new_item->name, XP_StripLine(gtr_than)); - } - } - - parseString = endQuote + 1; - - new_item = bm_check_read_alias(context, new_item, parseString); - - if (!BM_ISALIAS(new_item)) { - bm_check_nickname(context, new_item, parseString); - } - } - - return new_item; -} - - -/* ptr should point to the chars "'); - - /* find the end of the name */ - if (gtr_than) { - end = strcasestr(gtr_than, "d.header.target = bm_target(buffer, FALSE); - - new_item->addition_date = bm_addition_date(buffer); - - if (bm_is_folded(buffer)) - BM_SETFLAG(new_item, BM_ATTR_FOLDED); - else - BM_CLEARFLAG(new_item, BM_ATTR_FOLDED); - - new_item = bm_check_read_alias(context, new_item, buffer); - - if (!BM_ISALIAS(new_item)) { - if (context->type == MWContextAddressBook) { - bm_check_nickname(context, new_item, buffer); - } else { - if (strcasestr(buffer, "MENUHEADER")) f->menuheader = new_item; - if (strcasestr(buffer, "NEWITEMHEADER")) f->addheader = new_item; - } - } - - } - - return new_item; -} - - - -static void -bm_read_description(BM_Entry* new_item, char* buffer ) -{ - char* ptr; - char* end; - int length; - - /* assume the rest is descriptions; ignore if item is not a reasonable - type */ - - if (!new_item || !buffer) return; - - switch (new_item->type) { - case BM_TYPE_HEADER: - case BM_TYPE_URL: - case BM_TYPE_ADDRESS: - - length = XP_STRLEN(buffer); - - /* skip
    if present */ - if (*buffer == '<') { - buffer += 4; - length -= 4; - } - - if (length <= 0) return; - - end = buffer + length - 1; - - /* check for
    on the end and remove it also add a return */ - if (*end == '>') { - end -= 3; - XP_STRCPY(end, LINEBREAK); - end += LINEBREAK_LEN; - *end = '\0'; - } else { - end++; - XP_STRCPY(end, LINEBREAK); - end += LINEBREAK_LEN; - *end = '\0'; - } - - /* go through and turn < into '<' */ - for (ptr = buffer, end = buffer; *end != '\0'; end++) { - if (!strncasecomp(end, "<", 4)) { - end += 3; - *ptr++ = '<'; - } else { - *ptr++ = *end; - } - } - *ptr = '\0'; /* terminate */ - StrAllocCat(new_item->description, buffer); - } -} - - - - -/* Find the next entry after this one, where "next" means "the one that would - show up on the next line if we didn't fold any headers". Also, this will - wrap around from the end back to the beginning. In other words, it will - never return NULL. */ -static BM_Entry* -bm_GetNextSpanningWrapping(MWContext* context, BM_Entry* at) -{ - if (BM_ISHEADER(at) && at->d.header.children) return at->d.header.children; - if (at->next) return at->next; - do { - at = at->parent; - if (at && at->next) { - return at->next; - } - } while (at); - return BM_GetRoot(context); -} - - - -static XP_Bool -bm_StringMatches(MWContext* context, BM_FindInfo* findInfo, const char* str) { - char* ptr; - INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context); - if (!str) return FALSE; - if (findInfo->matchCase) { - ptr = INTL_Strstr(INTL_GetCSIWinCSID(c), str, findInfo->textToFind); - } else { - ptr = INTL_Strcasestr(INTL_GetCSIWinCSID(c), str, findInfo->textToFind); - } - if (!ptr) return FALSE; - if (findInfo->matchWholeWord) { - XP_ASSERT(ptr >= str); - XP_ASSERT(ptr + XP_STRLEN(findInfo->textToFind) <= str + XP_STRLEN(str)); - if (ptr != str && !isspace(ptr[-1]) && !ispunct(ptr[-1])) return FALSE; - ptr += XP_STRLEN(findInfo->textToFind); - if (*ptr != '\0' && !isspace(*ptr) && !ispunct(*ptr)) return FALSE; - } - return TRUE; -} - - -static XP_Bool -bm_IsMatch(MWContext* context, BM_Entry* entry, BM_FindInfo* findInfo) -{ - - if(!context) - return FALSE; - - if (BM_ISALIAS(entry)) entry = entry->d.alias.original; - if (findInfo->checkNickname) { - if (bm_StringMatches(context, findInfo, entry->nickname)) return TRUE; - } - if (findInfo->checkName) { - if (bm_StringMatches(context, findInfo, BM_GetName(entry))) return TRUE; - } - if (findInfo->checkLocation && BM_ISURL(entry)) { - if (bm_StringMatches(context, findInfo, entry->d.url.address)) return TRUE; - } - if (findInfo->checkDescription) { - if (bm_StringMatches(context, findInfo, entry->description)) return TRUE; - } - return FALSE; -} - -static BM_Entry* -bm_DoFindBookmark_1(MWContext* context, BM_Entry* at, BM_FindInfo* findInfo) { - BM_Entry* start = at; - if (!at) return NULL; - do { - if (bm_IsMatch(context, at, findInfo)) return at; - at = bm_GetNextSpanningWrapping(context, at); - } while (at != start); - return NULL; -} - -/* reads an item from fp using the specified buffer and relative_url */ -static void -bm_ReadFromHTML(MWContext* context, - XP_File fp, - BM_Entry* item, - char* buffer, - const char* relative_url) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* new_item = NULL; - char* buffer_ptr; - char* ptr; - uint16 type; - - /* read loop */ - while (XP_FileReadLine(buffer, READ_BUFFER_SIZE, fp)) { - buffer_ptr = XP_StripLine(buffer); - - type = bm_tokenize_line(context, buffer_ptr, &ptr); - - switch (type) { - case BM_TYPE_URL: - new_item = bm_read_url(context, fp, buffer_ptr, ptr, relative_url); - break; - - case BM_TYPE_ADDRESS: - new_item = bm_read_address(context, fp, buffer_ptr, ptr); - break; - - case BM_TYPE_HEADER: - new_item = bm_read_header(context, buffer_ptr, ptr); - break; - - case BM_TYPE_SEPARATOR: - if (context->type == MWContextBookmarks) { - new_item = bm_NewSeparator(); - } - break; - - case BM_HEADER_END: - if (item != f->gBookmarks) return; - break; - - case BM_UNKNOWN: - if (new_item) - bm_read_description(new_item, buffer_ptr); - else if (item) - bm_read_description(item, buffer_ptr); - break; - } - - /* test for insertable item -- nb you'll need - to update this if you add new types/items */ - if (new_item && (type == BM_TYPE_URL || - type == BM_TYPE_HEADER || - type == BM_TYPE_SEPARATOR || - type == BM_TYPE_ADDRESS)) { - if (!item) { - if (!f->gBookmarks) { - if (new_item->type == BM_TYPE_HEADER) { - f->gBookmarks = new_item; - if (context->type == MWContextBookmarks) { - f->menuheader = f->addheader = new_item; - } - goto SKIP; - } else { - (void) BM_GetRoot(context); /* Has side effect of creating - root header. */ - if (!f->gBookmarks) return; - } - } - item = f->gBookmarks; - } - - if (context->type == MWContextBookmarks) { - bm_AppendChildToHeader(context, item, new_item); - } else { - bm_AddChildToHeaderSorted(context, item, new_item); - } - -SKIP: - /* if it's a header, recurse */ - if (new_item->type == BM_TYPE_HEADER) { - bm_ReadFromHTML(context, fp, new_item, buffer, relative_url); - } - } - } -} - -static int -bm_WriteAsHTML(MWContext* context, XP_File fp, BM_Entry* item, int32 level, - XP_Bool isalias); - - -static int -bm_write_ok(const char* str, int length, XP_File fp) -{ - if (length < 0) - length = XP_STRLEN(str); - if (length > WRITE_BUFFER_SIZE) - length = WRITE_BUFFER_SIZE; - if ((int) XP_FileWrite(str, length, fp) < length) - return -1; - return 0; -} - - -#define WRITE(str, length, fp) \ -if (bm_write_ok((str), (length), (fp)) < 0) return -1 - -static int -bm_write_alias_info(MWContext* context, XP_File fp, BM_Entry* entry, - XP_Bool isalias) -{ - bm_alias_info* info; - XP_ASSERT(!isalias || (entry->flags & BM_ATTR_HASALIASES)); - if (entry->flags & BM_ATTR_HASALIASES) { - if (!isalias) { - /* Well, we think we have some aliases, but we can't be sure. Let's - make sure. */ - if (BM_CountAliases(context, entry) == 0) return 0; - } - info = bm_find_writealias_info(context, entry); - WRITE(isalias ? " ALIASOF=\"" : " ALIASID=\"", -1, fp); - WRITE(info->id, -1, fp); - WRITE("\"", -1, fp); - } - return 0; -} - - -static int -bm_write_nickname(MWContext* context, XP_File fp, BM_Entry* entry, - XP_Bool isalias) -{ - if (context->type == MWContextAddressBook && !isalias && - entry->nickname && *entry->nickname) { - WRITE(" NICKNAME=\"", -1, fp); - WRITE(entry->nickname, -1, fp); - WRITE("\"", -1, fp); - } - return 0; /* XXX This was left out. Is is 0 right? */ -} - - - -static int -bm_write_html_header(MWContext* context, XP_File fp, BM_Entry* item, - int32 level, XP_Bool isalias) -{ - BM_Frame* f = GETFRAME(context); - char buffer[16]; - int32 i; - BM_Entry* child; - char* target; - int status; - - XP_ASSERT(BM_ISHEADER(item)); - - target = BM_GetTarget(item, FALSE); - - if (level != 0) { - if (item->name) { - WRITE("
    flags & BM_ATTR_FOLDED) { - WRITE(" FOLDED", -1, fp); - } - - if (item == f->menuheader) { - WRITE(" MENUHEADER", -1, fp); - } - if (item == f->addheader) { - WRITE(" NEWITEMHEADER", -1, fp); - } - - status = bm_write_alias_info(context, fp, item, isalias); - if (status < 0) return status; - - status = bm_write_nickname(context, fp, item, isalias); - if (status < 0) return status; - - /* write target */ - if ((target)&&(target[0] != '\0')) - { - WRITE(" TARGET=\"", -1, fp); - WRITE(target, -1, fp); - WRITE("\"", -1, fp); - } - - if (context->type == MWContextBookmarks) { - /* write addition date */ - WRITE(" ADD_DATE=\"", -1, fp); - XP_SPRINTF(buffer, "%ld\"", item->addition_date); - WRITE(buffer, XP_STRLEN(buffer), fp); - } - WRITE(">", -1, fp); - - /* write name */ - WRITE(item->name, XP_STRLEN(item->name), fp); - WRITE("", -1, fp); - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - } - } - - /* write description if there is one */ - if (item->description) { - char *ptr = XP_StripLine(item->description); - - WRITE("
    ", -1, fp); - - for (; *ptr != '\0'; ptr++) { - if (*ptr == '<') { - WRITE("<", -1, fp); - } else if (*ptr == '\n') { - WRITE("
    ", -1, fp); - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - } else { - WRITE(ptr, 1, fp); - } - } - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - } - - if (!isalias) { - /* write children out */ - for (i = 0; i < level; i++) { - WRITE(" ", -1, fp); /* indent */ - } - WRITE("

    " LINEBREAK, -1, fp); - - for (child = item->d.header.children; child ; child = child->next) { - bm_WriteAsHTML(context, fp, child, level + 1, FALSE); - } - - for (i = 0; i < level; i++) { - WRITE(" ", -1, fp); - } - - WRITE("

    " LINEBREAK, -1, fp); - } - return 0; -} - -static int -bm_write_separator(XP_File fp) -{ - WRITE("


    ", -1, fp); - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - return 0; -} - -static int -bm_write_address( char *pszAddress, XP_File fp ) -{ - /* - // Replace explicit quotes with escaped quotes before writing the address. - // For example: - // javascript:netscape.plugin.composer.Document.editDocument("http://myserver.com/docs/schedule.html") - // is converted to: - // javascript:netscape.plugin.composer.Document.editDocument(%20http://myserver.com/docs/schedule.html%20) - */ - - int iBufPos, iLen = 0; - char * pszCsr = pszAddress; - char * pszBuf = NULL; - - if( !pszAddress || !fp ) - { - return 0; - } - - if( !XP_STRCHR( pszAddress, '"' ) ) - { - /* No quotes to convert, so just write it and return. */ - - WRITE( pszAddress, -1, fp ); - return 0; - } - - /* - // Calculate the size of the new string. - */ - iLen = XP_STRLEN( pszAddress ); - while( *pszCsr ) - { - if( *pszCsr == '"' ) - { - iLen += 2; - } - pszCsr++; - } - - pszBuf = (char *)XP_ALLOC( iLen+1 ); - if( !pszBuf ) - { - return 0; - } - - /* - // Copy the url while converting explicit quotes to escaped quotes. - */ - iBufPos = 0; - pszCsr = pszAddress; - while( *pszCsr ) - { - if( *pszCsr == '"' ) - { - pszBuf[iBufPos] = '%'; - pszBuf[++iBufPos] = '2'; - pszBuf[++iBufPos] = '2'; - } - else - { - pszBuf[iBufPos] = *pszCsr; - } - - iBufPos++; - pszCsr++; - } - pszBuf[iBufPos] = 0; - - /* Finally write out the converted address */ - - WRITE( pszBuf, -1, fp ); - - XP_FREE( pszBuf ); - - return 0; -} - -/* writes out a URL entry to look like: - * - *
    Internet Talk Radio - * - */ -static int -bm_write_url_or_address(MWContext* context, XP_File fp, BM_Entry* item, - XP_Bool isalias) -{ - char buffer[16]; - char* address; - char* target; - int status; - - address = BM_GetAddress(item); - target = BM_GetTarget(item, FALSE); - - if (address) { - WRITE("
    ", -1, fp); - - /* write address */ - WRITE("type == MWContextAddressBook) { - WRITE("mailto:", -1, fp); - } - bm_write_address(address, fp); - WRITE("\"", -1, fp); - - /* write target */ - if ((target)&&(target[0] != '\0')) - { - WRITE(" TARGET=\"", -1, fp); - WRITE(target, -1, fp); - WRITE("\"", -1, fp); - } - - status = bm_write_alias_info(context, fp, item, isalias); - if (status < 0) return status; - - status = bm_write_nickname(context, fp, item, isalias); - if (status < 0) return status; - - if (BM_ISURL(item)) { - /* write the addition date */ - WRITE(" ADD_DATE=\"", -1, fp); - XP_SPRINTF(buffer, "%ld", item->addition_date); - WRITE(buffer, -1, fp); - WRITE("\"", -1, fp); - - /* write the last visited date */ - WRITE(" LAST_VISIT=\"", -1, fp); - XP_SPRINTF(buffer, "%ld\"", item->d.url.last_visit); - WRITE(buffer, -1, fp); - - /* write the last modified date */ - WRITE(" LAST_MODIFIED=\"", -1, fp); - XP_SPRINTF(buffer, "%ld\"", item->d.url.last_modified); - WRITE(buffer, -1, fp); - } - WRITE(">", -1, fp); - - /* write the name */ - - if (item->name) { - WRITE(item->name, -1, fp); - } else { - if (BM_ISURL(item)) { - WRITE(item->d.url.address, -1, fp); - } else { - XP_ASSERT(BM_ISADDRESS(item)); - WRITE(item->d.address.address, -1, fp); - } - } - - WRITE("", -1, fp); - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - - /* write description if there is one */ - if (item->description) { - char *ptr = XP_StripLine(item->description); - - WRITE("
    ", -1, fp); - - for (; *ptr != '\0'; ptr++) { - if (*ptr == '<') { - WRITE("<", -1, fp); - } else if (*ptr == '\n') { - WRITE("
    ", -1, fp); - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - } else { - WRITE(ptr, 1, fp); - } - } - WRITE(LINEBREAK, LINEBREAK_LEN, fp); - } - } - return 0; -} - - -/* writes an item into fp at the specified indentation level */ -static int -bm_WriteAsHTML(MWContext* context, XP_File fp, BM_Entry* item, int32 level, - XP_Bool isalias) -{ - int32 i; - int status = 0; - - /* indent */ - if (!isalias) { - for (i = 0; i < level; i++) { - WRITE(" ", -1, fp); - } - } - - switch (item->type) { - case BM_TYPE_HEADER: - status = bm_write_html_header(context, fp, item, level, isalias); - break; - - case BM_TYPE_SEPARATOR: - status = bm_write_separator(fp); - break; - - case BM_TYPE_URL: - case BM_TYPE_ADDRESS: - status = bm_write_url_or_address(context, fp, item, isalias); - break; - - case BM_TYPE_ALIAS: - XP_ASSERT(!isalias); - status = bm_WriteAsHTML(context, fp, item->d.alias.original, level, TRUE); - break; - } - return status; -} - -/* clears the selected state of parent and all of it's children - if refresh is TRUE, the FE is called to redraw necessary items - count should match the index of parent in the visible tree. count will - be NULL if a parent is folded. */ -PRIVATE void -bm_ClearSelection(MWContext* context, BM_Entry* parent, XP_Bool refresh, int32* count) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* child; - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - - if (parent->flags & BM_ATTR_SELECTED) { - BM_CLEARFLAG(parent, BM_ATTR_SELECTED); - if (refresh && count) bm_refresh(context, *count, *count); - f->gSelectionCount = -9999; - } - - if (count) (*count)++; - - if (BM_ISFOLDED(parent)) count = NULL; - - for (child = parent->d.header.children ; child ; child = child->next) { - if (child->type != BM_TYPE_HEADER) { - if (child->flags & BM_ATTR_SELECTED) { - BM_CLEARFLAG(child, BM_ATTR_SELECTED); - if (refresh && count) bm_refresh(context, *count, *count); - f->gSelectionCount = -9999; - } - if (count) (*count)++; - } else { - bm_ClearSelection(context, child, refresh, count); - } - } -} - -PRIVATE void -bm_SelectAll(MWContext* context, BM_Entry* parent) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* child; - - XP_ASSERT(parent); - XP_ASSERT(parent->type == BM_TYPE_HEADER); - - child = parent->d.header.children; - if (!BM_ISSELECTED(parent)) - { - BM_SETFLAG(parent, BM_ATTR_SELECTED); - f->gSelectionCount++; - f->gSelectionMask |= BM_TYPE_HEADER; - } - - while (child) - { - if (BM_ISHEADER(child)) - bm_SelectAll(context, child); - else - { - if (!(child->flags & BM_ATTR_SELECTED)) - { - BM_SETFLAG(child, BM_ATTR_SELECTED); - f->gSelectionCount++; - f->gSelectionMask |= child->type; - } - } - child = child->next; - } -} - -PUBLIC void -BM_SelectAll(MWContext* context, XP_Bool refresh) -{ - BM_Entry* root; - CHKCONTEXTVOID(context); - - root = BM_GetRoot(context); - - if (root) - { - bm_SelectAll(context, root); - if (refresh) - bm_refresh(context, 1, BM_LAST_CELL); - } -} - -static void -bm_TellGoingAway(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_Frame* f = GETFRAME(context); - if (entry == f->menuheader) { - BM_SetMenuHeader(context, BM_GetRoot(context)); - } - if (entry == f->addheader) { - BM_SetAddHeader(context, BM_GetRoot(context)); - } - BMFE_EntryGoingAway(context, entry); - if (entry->nickname) { - BM_SetNickName(context, entry, NULL); /* Causes the nickname hash to be - cleared, adding undo stuff to - bring it back if this entry - somehow gets brought back. */ - XP_ASSERT(entry->nickname == NULL); - } -#ifdef DEBUG - /* Confirm that we are not deleting any dangling aliases. */ - if (entry->flags & BM_ATTR_HASALIASES) { - int32 count = BM_CountAliases(context, entry); - if (count) { - BM_Entry* deleteroot = (BM_Entry*) closure; - if (BM_ISHEADER(deleteroot)) { - /* Reduce the count by the number of aliases that we're going to - delete. */ - count -= bm_CountAliases_1(deleteroot, entry); - } - XP_ASSERT(count == 0); - } - } -#endif /* DEBUG */ -} - -/* free's a bmlist entry */ -PRIVATE void -bm_ShallowFreeEntry(BM_Entry* entry) -{ - if (entry) { - XP_ASSERT(entry->next == NULL); - XP_ASSERT(entry->nickname == NULL); - - FREEIF(entry->name); - FREEIF(entry->description); - switch (entry->type) { - case BM_TYPE_HEADER: - XP_ASSERT(entry->d.header.children == NULL); - break; - - case BM_TYPE_URL: - FREEIF(entry->d.url.address); - FREEIF(entry->d.url.content_type); - break; - - case BM_TYPE_ADDRESS: - FREEIF(entry->d.address.address); - break; - } - XP_FREE(entry); - } -} - -PRIVATE void -bm_ReallyFreeEntry(void* data) -{ - BM_Entry* entry = (BM_Entry*) data; - while (entry) { - BM_Entry* next = entry->next; - entry->next = NULL; - if (BM_ISHEADER(entry)) { - /* free all the children */ - bm_ReallyFreeEntry(entry->d.header.children); - entry->d.header.children = NULL; - } - bm_ShallowFreeEntry(entry); - entry = next; - } -} - - -typedef struct bm_free_info { - BM_Entry* entry; - XP_Bool usedFromUndo; -} bm_free_info; - -static int -bm_cancel_free(void* closure) -{ - bm_free_info* info = (bm_free_info*) closure; - info->usedFromUndo = TRUE; - return 0; -} - - -static void -bm_free_freeit(void* closure) -{ - bm_free_info* info = (bm_free_info*) closure; - if (!info->usedFromUndo) bm_ReallyFreeEntry(info->entry); - XP_FREE(info); -} - - -/* free's a BM_Entry and all of its succeeding siblings... if it's a - header, it frees all of its children. However, actually this - does nothing, but logs an event in the undo queue. When the event gets - freed, then we know that nothing in the undo chain needs this thing, - so *then* we can free it.*/ -void -BM_FreeEntry(MWContext* context, BM_Entry* entry) -{ - BM_Frame* f = GETFRAME(context); - if (!entry) return; - - bm_start_batch(context); - bm_EachEntryDo_1(context, entry, bm_TellGoingAway, entry); - - if (f->undo) { - bm_free_info* info = XP_NEW_ZAP(bm_free_info); - if (!info) { - UNDO_DiscardAll(f->undo); - bm_ReallyFreeEntry(entry); - } else { - info->entry = entry; - UNDO_LogEvent(f->undo, bm_cancel_free, bm_free_freeit, info, NULL, NULL); - } - } else { - bm_ReallyFreeEntry(entry); - } - bm_end_batch(context); -} - - - -int -BM_InitializeBookmarksContext(MWContext* context) -{ - BM_Frame* f; - XP_ASSERT(context); - if (!context) return -1; /* ### Need better error code? */ - f = XP_NEW_ZAP(BM_Frame); - if (!f) return MK_OUT_OF_MEMORY; - XP_ASSERT(context->bmframe == NULL); - f->undo = UNDO_Create(10); - if (!f->undo) goto FAIL; - f->nicknameTable = XP_HashTableNew(100, XP_StringHash, bm_string_cmp); - if (!f->nicknameTable) goto FAIL; - f->errorSavingBookmarks = FALSE; - f->enSortType = BM_Sort_Natural; - f->bSorting = FALSE; - context->bmframe = f; - f->next = ContextList; - ContextList = context; - (void) BM_GetRoot(context); /* Has side effect of creating root header. */ - bm_refresh(context, 1, BM_LAST_CELL); - return 0; -FAIL: - if (f->undo) UNDO_Destroy(f->undo); - if (f->nicknameTable) XP_HashTableDestroy(f->nicknameTable); - XP_FREE(f); - return MK_OUT_OF_MEMORY; -} - -void -BM_CleanupBookmarksContext(MWContext* context) -{ - BM_Frame* f; - MWContext** tmp; - CHKCONTEXTVOID(context); - BM_SaveBookmarks(context, NULL); - - /* This cleanup code can be slow and - inefficient. Since we're gonna exit soon - anyway, let's not bother doing this stuff. - ### - DMB - Let's, at least for debug - detection of meory leaks. How slow could it - be? */ - f = GETFRAME(context); - UNDO_Destroy(f->undo); - f->undo = NULL; - BM_FreeEntry(context, f->gBookmarks); - if (f->savetimer) { - FE_ClearTimeout(f->savetimer); - f->savetimer = NULL; - } - - f->gBookmarks = NULL; - if (f->aliasTable) { - bm_clear_alias_info(context); - XP_HashTableDestroy(f->aliasTable); - } - if (f->nicknameTable) { - XP_HashTableDestroy(f->nicknameTable); - } - - for (tmp = &ContextList ; *tmp ; tmp = &(f->next)) { - f = GETFRAME(*tmp); - if (*tmp == context) { - (*tmp)->bmframe = NULL; - *tmp = f->next; - XP_FREE(f); - return; - } - } - XP_ASSERT(0); -} - - -/* returns TRUE if the bookmarks have been modified since -the file was read, FALSE otherwise */ -PUBLIC XP_Bool -BM_Modified(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXT(context); - return f ? f->gBookmarksModified : FALSE; -} - -static void -bm_UpdateTimeStamp(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_Date cur_time = *(BM_Date *)closure; - BM_Frame* f = GETFRAME(context); - int32 oldstate; - - if (!entry) return; - - oldstate = BM_GetChangedState(entry); - entry->d.url.last_visit = cur_time; - if (entry->d.url.last_modified == 0) { - /* Well, this current visitation is a good enough estimate for the modification time. */ - entry->d.url.last_modified = cur_time; - } - - /* Deliberately *don't* call bm_SetModified here; we don't want to cause - the file to be saved soon for this trivial change. Just turn on the - modified bit so that we know things will be saved eventually. */ - f->gBookmarksModified = TRUE; - - if (BM_GetChangedState(entry) != oldstate) { - bm_entry_changed(context, entry); - } -} - -/* checks the bmlist for a url and updates the last accessed time */ -PUBLIC void -BM_UpdateBookmarksTime(URL_Struct* URL_s, BM_Date cur_time) -{ - MWContext* context; - BM_Frame* f; - - if (!URL_s) return; - - for (context = ContextList ; context ; context = f->next) { - f = GETFRAME(context); - if (context->type != MWContextBookmarks) continue; - bm_FindItemStub(context, BM_GetRoot(context), URL_s->address, bm_UpdateTimeStamp, (void *)&cur_time); - } -} - - -/* returns the total number of items in the tree */ -PUBLIC int32 -BM_GetCount(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXT(context); - if (!f) return 0; - if (f->gCount <= 0) { - f->gCount = bm_CountChildren(BM_GetRoot(context), FALSE); - } - return f->gCount; -} - -/* returns the number of items in the tree that are presently - visible */ -PUBLIC int32 -BM_GetVisibleCount(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXT(context); - if (!f) return 0; - if (f->gVisCount <= 0) { - f->gVisCount = bm_CountChildren(BM_GetRoot(context), TRUE); - } - return f->gVisCount; -} - - - - - -static void -bm_InsertItemAfter(MWContext* context, BM_Entry* insert_after, - BM_Entry* insertee, XP_Bool sync) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - - XP_ASSERT(insertee); - if (!insertee) return; - - /* insert after the item if specified */ - if (insert_after) - { - BM_Entry* tmp; - BM_Entry* parent; - - if (insert_after->parent == NULL) - { - /* insert as first child, displayed below header */ - tmp = insert_after->d.header.children; - parent = insert_after; - parent->d.header.childCount++; - parent->d.header.children = insertee; - } - else - { - tmp = insert_after->next; - parent = insert_after->parent; - - if (parent) - { - parent->d.header.childCount++; - if (!tmp) - parent->d.header.lastChild = insertee; - } - insert_after->next = insertee; - } - insertee->next = tmp; - insertee->parent = parent; - - if( !f->bSorting ) - insertee->iNaturalIndex = g_iNaturalIndexPool++; - - BMFE_BookmarkMenuInvalid(context); - bm_LogDeleteChild(context, parent, insertee); - } - else - bm_AppendChildToHeader(context, BM_GetRoot(context), insertee); - - bm_SetModified(context, TRUE); - if (sync) - bm_SyncCount(context); -} - -/* insert an item after another item in the bmlist - if the insert_after item is NULL the item - will be inserted at the end of the bookmarks */ -PUBLIC void -BM_InsertItemAfter(MWContext* context, BM_Entry* insert_after, BM_Entry* insertee) -{ - CHKCONTEXTVOID(context); - bm_start_batch(context); - bm_InsertItemAfter(context, insert_after, insertee, TRUE); - bm_end_batch(context); -} - -/* insert an item in a header if "insert_after" is a - Header type, or after the item if "insert after" is - not a header type. - if the insert_after item is NULL or not found the item - will be inserted at the end of the bookmarks */ -PUBLIC void -BM_InsertItemInHeaderOrAfterItem( MWContext* context, - BM_Entry* insert_after, - BM_Entry* insertee) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(insertee); - - bm_start_batch(context); - if (insert_after && insert_after->type == BM_TYPE_HEADER) - bm_AppendChildToHeader(context, insert_after, insertee); - else - BM_InsertItemAfter(context, insert_after, insertee); - bm_SyncCount(context); - bm_end_batch(context); -} - -static void remove_to(MWContext* context, BM_Entry* entry, void* to) -{ - BM_Entry* moveTo = (BM_Entry*)to; - BM_Entry* parent; - - XP_ASSERT(entry); - - parent = entry->parent; - if (parent) - BM_RemoveChildFromHeader(context, parent, entry); - - bm_AppendChildToHeader(context, moveTo, entry); -} - - - -static int -bm_get_max_depth_1(BM_Entry* entry) -{ - int result = 0; - for (; entry ; entry = entry->next) { - if (BM_ISHEADER(entry) && !BM_ISFOLDED(entry)) { - int value = bm_get_max_depth_1(entry->d.header.children); - if (result < value) result = value; - } - } - return result + 1; -} - -int -BM_GetMaxDepth(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXT(context); - if (!f) return 0; - if (f->max_depth == 0) { - f->max_depth = bm_get_max_depth_1(f->gBookmarks); - } - return f->max_depth; -} - - -PUBLIC XP_Bool -BM_IsDragEffectBox(MWContext* context, int line, XP_Bool under) -{ - BM_Entry* entry; - CHKCONTEXT(context); - if (line <= 0) return FALSE; - entry = BM_AtIndex(context, line); - if (!entry) return FALSE; /* ### */ - if (BM_ISHEADER(entry)) { - if (under && (BM_ISFOLDED(entry) || entry->d.header.childCount == 0)) { - return FALSE; - } - return TRUE; - } - return FALSE; -} - - -PUBLIC void -BM_DoDrop(MWContext* context, int line, XP_Bool under) -{ - BM_Entry* dest = BM_AtIndex(context, line); - BM_Entry* tmp; - BM_Entry* parent; - BM_Entry* entry; - CHKCONTEXTVOID(context); - if (!dest) return; - for (parent = dest ; parent ; parent = parent->parent) { - if (BM_ISSELECTED(parent)) return; - } - tmp = BM_NewHeader(""); - if (!tmp) return; - bm_start_batch(context); - if (BM_ISHEADER(dest) && BM_IsDragEffectBox(context, line, under)) { - parent = dest; - dest = NULL; - } else { - parent = dest->parent; - } - BM_EachProperSelectedEntryDo(context, remove_to, tmp, NULL); - entry = tmp->d.header.children; - if (entry) { - BM_ClearAllSelection(context, FALSE); - while ((entry = tmp->d.header.children)) { - BM_RemoveChildFromHeader(context, tmp, entry); - BM_CLEARFLAG(entry, BM_ATTR_SELECTED); - if (context->type == MWContextBookmarks) { - if (dest) { - bm_InsertItemAfter(context, dest, entry, FALSE); - } else { - BM_PrependChildToHeader(context, parent, entry); - } - } else { - if (BM_ISALIAS(entry)) { - bm_AddChildToHeaderSorted(context, parent, entry); - } else { - bm_AddChildToHeaderSorted(context, BM_GetRoot(context), entry); - entry = bm_NewAlias(entry); - bm_AddChildToHeaderSorted(context, parent, entry); - } - } - if (!BM_ISHEADER(parent) || !BM_ISFOLDED(parent)) - BM_SelectItem(context, entry, FALSE, TRUE, TRUE); - dest = entry; - entry = tmp->d.header.children; - } - if (BM_ISHEADER(parent) && BM_ISFOLDED(parent)) - BM_SelectItem(context, parent, FALSE, TRUE, TRUE); - BMFE_BookmarkMenuInvalid(context); - bm_SyncCount(context); - bm_refresh(context, 1, BM_LAST_CELL); - } - BM_FreeEntry(context, tmp); - bm_end_batch(context); -} - - - -typedef struct bm_goingaway_info { - XP_Bool userasked; - XP_Bool userconfirmed; - BM_Entry* entry; - int count; -} bm_goingaway_info; - - -static void -bm_subtract_alias_for(MWContext* context, BM_Entry* entry, void* closure) -{ - bm_goingaway_info* info = (bm_goingaway_info*) closure; - if (BM_ISALIAS(entry) && entry->d.alias.original == info->entry) { - info->count--; - } -} - - -static void -bm_delete_alias_for(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_Entry* base = (BM_Entry*) closure; - if (BM_ISALIAS(entry) && entry->d.alias.original == base) { - BM_RemoveChildFromHeader(context, entry->parent, entry); - BM_FreeEntry(context, entry); - } -} - - - -static void -bm_check_dangling_aliases(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_Frame* f = GETFRAME(context); - bm_goingaway_info* info = (bm_goingaway_info*) closure; - if (entry->flags & BM_ATTR_HASALIASES) { - info->count = BM_CountAliases(context, entry); - if (info->count) { - /* Reduce the count by the number of aliases that we're going to - delete. */ - info->entry = entry; - BM_EachProperSelectedEntryDo(context, bm_subtract_alias_for, info, NULL); - XP_ASSERT(info->count >= 0); - if (info->count) { - if (!info->userasked) { - if (f->gSelectionCount < 0) bm_SyncSelection(context); - if (f->gSelectionCount == 1) { - char* buf = (char*) XP_ALLOC(512); - if (buf) { - XP_SPRINTF(buf, - XP_GetString(XP_BKMKS_REMOVE_THIS_ITEMS_ALIASES), info->count); - info->userconfirmed = FE_Confirm(context, buf); - XP_FREE(buf); - } else { - info->userconfirmed = - FE_Confirm - (context, - XP_GetString(XP_BKMKS_REMOVE_SOME_ITEMS_ALIASES) ); - } - info->userasked = TRUE; - } - if (info->userconfirmed) { - BM_EachEntryDo(context, bm_delete_alias_for, entry); - } - } - } - } - } -} - -static void -bm_delete(MWContext* context) -{ - BM_Entry* tmp; - struct BM_Entry_Focus bmFocus; - bm_goingaway_info info; - - tmp = BM_NewHeader(""); - XP_ASSERT(tmp); - if (!tmp) return; - - XP_MEMSET(&info, 0, sizeof(info)); - BM_EachProperSelectedEntryDo(context, bm_check_dangling_aliases, &info, - NULL); - if (info.userasked && !info.userconfirmed) return; - - bmFocus.saveFocus = (BM_Entry*) NULL; - bmFocus.foundSelection = FALSE; - BM_EachProperSelectedEntryDo(context, remove_to, tmp, &bmFocus); - - BM_FreeEntry(context, tmp); - bm_SyncCount(context); - - if (bmFocus.saveFocus == NULL) - bmFocus.saveFocus = BM_GetRoot(context); - if (bmFocus.saveFocus) - BM_SETFLAG(bmFocus.saveFocus, BM_ATTR_SELECTED); - bm_refresh(context, 1, BM_LAST_CELL); -} - - -static void -bm_copy(MWContext* context) -{ - char* block; - int32 length; - - block = BM_ConvertSelectionsToBlock(context, TRUE, &length); - BMFE_SetClipContents(context, (void*)block, length); - - XP_FREE(block); -} - -static void -bm_cut(MWContext* context) -{ - bm_copy(context); - bm_delete(context); -} - - -static void -bm_paste(MWContext* context) -{ - BM_Entry* firstSelected; - char* buffer; - int32 length; - - firstSelected = BM_FirstSelectedItem(context); - buffer = (char*)BMFE_GetClipContents(context, &length); - if (buffer) - { - BM_InsertBlockAt(context, buffer, firstSelected, TRUE, length); - bm_SyncCount(context); - bm_refresh(context, 1, BM_LAST_CELL); - } -} - -/* Insert a block of long-format entries */ -PUBLIC void -BM_DropBlockL( MWContext *pContext, char *pData, BM_Entry *firstSelected ) -{ - int32 length; - - if( !firstSelected ) - { - firstSelected = BM_FirstSelectedItem( pContext ); - } - - if( pData ) - { - /* Length is stored at byte 0 as int32 */ - XP_MEMCPY( &length, pData, sizeof(int32) ); - pData += sizeof(int32); - - BM_InsertBlockAt( pContext, pData, firstSelected, TRUE, length ); - bm_SyncCount( pContext ); - bm_refresh( pContext, 1, BM_LAST_CELL ); - } -} - -/* returns an integer index of the item in the visible tree */ -int32 -BM_GetIndex(MWContext* context, BM_Entry* item) -{ - int32 count = 1; - - CHKCONTEXT(context); - - if (BM_GetRoot(context)) - return bm_GetIndexNum(BM_GetRoot(context), item, &count); - else - return 0; -} - -/* returns an integer index of the item in the list and does not pay - attention to the BM_ATTR_FOLDED value */ -int32 -BM_GetUnfoldedIndex(MWContext* context, BM_Entry* item) -{ - int32 count = 1; - - BM_Entry* root = BM_GetRoot(context); - - CHKCONTEXT(context); - - if (root) - return bm_GetUnfoldedIndexNum(root, item, &count); - else - return 0; -} - -/* returns TRUE if the second argument is a direct - descendent of the first argument. - returns FALSE otherwise */ -PUBLIC XP_Bool -BM_IsDescendent(MWContext* context, BM_Entry* parent, BM_Entry* possible_child) -{ - int32 count = 1; - CHKCONTEXT(context); - - if ( parent && - parent->type == BM_TYPE_HEADER && - bm_GetUnfoldedIndexNum(parent, possible_child, &count)) - return TRUE; - - return FALSE; -} - - -/* returns an integer depth of the item in the list starting at zero */ -PUBLIC int32 -BM_GetDepth(MWContext* context, BM_Entry* item) -{ - CHKCONTEXT(context); - if (BM_GetRoot(context)) - return bm_GetDepth(BM_GetRoot(context), item); - else - return 0; -} - - -/* returns the item at "count" visible indexes below "item" */ -static BM_Entry* -bm_AtIndex(BM_Entry* item, int32* count) -{ - XP_ASSERT(item); - XP_ASSERT(item->type == BM_TYPE_HEADER); - - (*count)--; - - /* first check to see if parent is the node we are looking for */ - if (*count <= 0) - return item; - - if (!BM_ISFOLDED(item)) - { - BM_Entry* child; - - child = item->d.header.children; - while (child) - { - if (child->type == BM_TYPE_HEADER) - { - BM_Entry* rv = NULL; - - rv = bm_AtIndex(child, count); - if (rv) - return rv; - } - else - { - (*count)--; - if (*count <= 0) - return child; - } - child = child->next; - } - } - return NULL; -} - -/* returns the object associated with the index returned by BM_GetIndex() */ -BM_Entry* -BM_AtIndex(MWContext* context, int32 index) -{ - BM_Frame* f = GETFRAME(context); - static BM_Frame* last_f = NULL; - static BM_Entry* last_item = NULL; - static int32 last_index = -1; - - int32 count = index; - - CHKCONTEXT(context); - - /* only used the cached items if last_item is non-NULL and the - requested index is one more than the last requested index */ - if (last_f == f && last_item && (index == (last_index + 1))) - { - /* if we're not a header - or we're a header but folded, - or we're a header but have no children, - just go to the next item and set the local cache */ - if ( (last_item->type != BM_TYPE_HEADER) || - (last_item->flags & BM_ATTR_FOLDED) || - (! last_item->d.header.children)) - { - last_item = last_item->next; - if (last_item) - { - last_index = index; - return last_item; - } - else - { - last_index = -1; - return BM_AtIndex(context, index); - } - } - else - /* we're a header, we're unfolded, and we have children */ - { - last_item = last_item->d.header.children; - last_index = index; - return last_item; - } - } - - if (BM_GetRoot(context) && index > 0) - { - last_item = bm_AtIndex(BM_GetRoot(context), &count); - if (last_item) - { - last_f = f; - last_index = index; - return last_item; - } - } - return NULL; -} - -PRIVATE BM_Entry* -bm_GetUnfoldedIndex(BM_Entry* parent, int32* index) -{ - BM_Entry* child; - BM_Entry* rv = 0; - - XP_ASSERT(parent); - XP_ASSERT(parent->type == BM_TYPE_HEADER); - child = parent->d.header.children; - - while (child) - { - *(index) -= 1; - - if (*index <= 0) - return child; - - if (child->type == BM_TYPE_HEADER) - { - rv = bm_GetUnfoldedIndex(child, index); - - if (rv) - return rv; - } - child = child->next; - } - - return NULL; -} - -/* returns the object associated with the index returned by BM_GetUnfoldedIndex() */ -PUBLIC BM_Entry* -BM_AtUnfoldedIndex(MWContext* context, int32 index) -{ - CHKCONTEXT(context); - if (BM_GetRoot(context) && index > 0) - return bm_GetUnfoldedIndex(BM_GetRoot(context), &index); - else - return NULL; -} - - -static void -bm_fold_header_all(MWContext* context, BM_Entry* entry, XP_Bool fold, - XP_Bool refresh) -{ - if (BM_ISHEADER(entry)) { - BM_FoldHeader(context, entry, fold, refresh, FALSE); - for (entry = entry->d.header.children ; entry ; entry = entry->next) { - bm_fold_header_all(context, entry, fold, refresh); - } - } -} - - -/* folds the header bm - if fold is TRUE, the item becomes folded - else the item is unfolded - if refresh is TRUE, the FE is called to - redraw necessary items - if foldAll is TRUE, all headers appearing - below bm in the tree are folded or unfolded - according to "fold" -*/ -PUBLIC void -BM_FoldHeader(MWContext* context, BM_Entry* bm, XP_Bool fold, XP_Bool refresh, XP_Bool foldAll) -{ - BM_Frame* f = GETFRAME(context); - int32 firstChangedCell = 0; - - CHKCONTEXTVOID(context); - XP_ASSERT(bm); - if (!bm) return; - - bm_CancelLastFind(context); - - f->max_depth = 0; - if (foldAll) - { - bm_start_batch(context); - bm_fold_header_all(context, bm, fold, refresh); - bm_end_batch(context); - return; - } - else - { - - if (BM_ISFOLDED(bm) != fold) - { - int32 count; - firstChangedCell = BM_GetIndex(context, bm); - - count = firstChangedCell; - - if (bm) - { - if (fold) - { - if (firstChangedCell != 0) - BM_ClearAllChildSelection(context, bm, FALSE); - BM_SETFLAG(bm, BM_ATTR_FOLDED); - } - else - BM_CLEARFLAG(bm, BM_ATTR_FOLDED); - } - - } - } - - bm_SetModified(context, TRUE); - bm_SyncCount(context); - - if (foldAll) - firstChangedCell = MIN(1, firstChangedCell); - - if (refresh && (firstChangedCell != 0)) - bm_refresh(context, firstChangedCell, BM_LAST_CELL); -} - - - -/* clears the selection state of all items in the tree - if refresh is TRUE, the FE is called to redraw items - which need to be redrawn -*/ -PUBLIC void -BM_ClearAllSelection(MWContext* context, XP_Bool refresh) -{ - BM_Frame* f = GETFRAME(context); - int32 t = 1; - CHKCONTEXTVOID(context); - - bm_ClearSelection(context, BM_GetRoot(context), refresh, &t); - f->gSelectionCount = 0; - f->gSelectionMask = 0; -} - -/* Clears the selection state of all children of the item passed. - if refresh is TRUE, the FE is called to redraw items - which need to be redrawn -*/ -PUBLIC void -BM_ClearAllChildSelection(MWContext* context, BM_Entry* at, XP_Bool refresh) -{ - CHKCONTEXTVOID(context); - if (!at) return; - if (at->type != BM_TYPE_HEADER) - return; - at = at->d.header.children; - while (at) - { - if (BM_ISSELECTED(at)) - BM_SelectItem(context, at, refresh, TRUE, FALSE); - if ((at->type == BM_TYPE_HEADER) && (at->d.header.children)) - BM_ClearAllChildSelection(context, at->d.header.children, refresh); - at = at->next; - } -} - -/* selects the item - if refresh is TRUE, the FE is called to redraw the item - if extend is TRUE, the item is added to the selection - else the selection is cleared and the item becomes - the selection - if select is TRUE, the item is selected - else it is deselected - - if extend is FALSE and select is FALSE, the selection - becomes empty -*/ -PUBLIC void -BM_SelectItem(MWContext* context, BM_Entry* item, XP_Bool refresh, - XP_Bool extend, XP_Bool select) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - XP_ASSERT(item); - if (!item) return; - bm_start_batch(context); - bm_CancelLastFind(context); - if (!extend) { - BM_ClearAllSelection(context, refresh); - if (select) f->lastSelectedItem = item; - } - if (select) { - if (!BM_ISSELECTED(item)) f->gSelectionCount++; - f->gSelectionMask |= item->type; - BM_SETFLAG(item, BM_ATTR_SELECTED); - } else { - BM_CLEARFLAG(item, BM_ATTR_SELECTED); - f->gSelectionCount = -9999; - } - if (refresh) { - int32 index = BM_GetIndex(context, item); - if (index) bm_refresh(context, index, index); - } - if (!extend) BMFE_EditItem(context, item); - bm_end_batch(context); -} - - - -static BM_Entry* -bm_validate_selected_item(MWContext* context, BM_Entry* item) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* result; - for (; item ; item = item->next) { - if (item == f->lastSelectedItem && BM_ISSELECTED(item)) return item; - if (BM_ISHEADER(item) && !BM_ISFOLDED(item)) { - result = bm_validate_selected_item(context, item->d.header.children); - if (result) return result; - } - } - return NULL; -} - - - -static void -bm_select_range(MWContext* context, BM_Entry* item, int32 min, int32 max, - int32* cur) -{ - for (; item ; item = item->next) { - if (*cur >= min) { - if (*cur > max) return; - BM_SelectItem(context, item, FALSE, TRUE, TRUE); - } - (*cur)++; - if (BM_ISHEADER(item) && !BM_ISFOLDED(item)) { - bm_select_range(context, item->d.header.children, min, max, cur); - } - } -} - - - -void -BM_SelectRangeTo(MWContext* context, BM_Entry* item) -{ - BM_Frame* f = GETFRAME(context); - int32 min; - int32 max; - int32 cur; - CHKCONTEXTVOID(context); - XP_ASSERT(item); - if (!item) return; - /* First very carefully validate the lastSelectedItem pointer. That item - might have been deleted or something, and the code in question may not - have updated the lastSelectedItem pointer. So, we make sure that it still - points to a valid item, and that the item is selected. */ - f->lastSelectedItem = bm_validate_selected_item(context, - BM_GetRoot(context)); - if (!f->lastSelectedItem) { - BM_SelectItem(context, item, TRUE, FALSE, TRUE); - XP_ASSERT(f->lastSelectedItem == item); /* Not that we can do much if - this fails...*/ - return; - } - min = BM_GetIndex(context, f->lastSelectedItem); - max = BM_GetIndex(context, item); - if (min < 1 || max < 1) return; - if (min > max) { - int32 tmp = min; - min = max; - max = tmp; - } - bm_start_batch(context); - BM_ClearAllSelection(context, TRUE); - cur = 1; - bm_select_range(context, BM_GetRoot(context), min, max, &cur); - XP_ASSERT(BM_ISSELECTED(item)); /* More sanity checking; not */ - XP_ASSERT(BM_ISSELECTED(f->lastSelectedItem)); /* really much we can do if - these assertions fail.*/ - bm_refresh(context, min, max); - bm_end_batch(context); -} - - -/* toggles the selected state of the item -(see BM_SelectItem) */ -PUBLIC void -BM_ToggleItem(MWContext* context, BM_Entry* item, XP_Bool refresh, XP_Bool extend) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(item); - if (!item) return; - - if (item->flags & BM_ATTR_SELECTED) - BM_SelectItem(context, item, refresh, extend, FALSE); - else - BM_SelectItem(context, item, refresh, extend, TRUE); -} - - - -static XP_Bool -bm_ConfirmSave(MWContext* context) -{ -/* XP_Bool doSave = FALSE; - char* msg = "Save changes to %s?\n"; - - sprintf(msg, f->gFile); - - if (BM_Modified(context)) - doSave = FE_SimpleConfirm(msg); - return doSave; -*/ - return TRUE; -} - - -const char* -BM_GetFileName(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - return f->gFile; -} - - - -static XP_Bool -bm_insert_bogus_aliases(XP_HashTable table, const void* key, void* value, - void* closure) -{ - MWContext* context = (MWContext*) closure; - bm_alias_info* info = (bm_alias_info*) value; - if (info->entry->parent == NULL) { - /* This was an alias that was made up and inserted because we never could - find the real entry for it. So, now we had better insert it into the - tree. */ - if (context->type == MWContextBookmarks) { - bm_AppendChildToHeader(context, BM_GetRoot(context), info->entry); - } else { - bm_AddChildToHeaderSorted(context, BM_GetRoot(context), info->entry); - } - } - return TRUE; -} - - -/* Make sure the address book is sorted. */ -static void -bm_resort_headers(MWContext* context, BM_Entry* header) -{ - XP_Bool needssort; - BM_Entry* entry; - BM_Entry* prev; - for ( ; header ; header = header->next) { - if (BM_ISHEADER(header)) { - prev = NULL; - needssort = FALSE; - for (entry = header->d.header.children ; entry ; entry = entry->next) { - if (BM_ISHEADER(entry)) bm_resort_headers(context, entry); - if (prev && bm_SortAddressBook(prev, entry) > 0) { - needssort = TRUE; - } - prev = entry; - } - if (needssort) { - BM_SelectItem(context, header, FALSE, FALSE, TRUE); - bm_SortSelected(context, BM_Sort_Name); - } - } - } -} - - -/* read bmlist file from disk - pass in a file url */ -PUBLIC void -BM_ReadBookmarksFromDisk(MWContext* context, const char* filename, - const char* relative_url) -{ - BM_Frame* f = GETFRAME(context); - XP_File fp; - char* buffer; - UndoState* undo; - - CHKCONTEXTVOID(context); - - undo = f->undo; - if (BM_Modified(context)) { - if (!bm_ConfirmSave(context)) return; - if (BM_SaveBookmarks(context, f->gFile) < 0) return; - } - if (f->gBookmarks) BM_FreeEntry(context, f->gBookmarks); - f->gBookmarks = NULL; - - buffer = (char*) XP_ALLOC(READ_BUFFER_SIZE); - if (!buffer) return; - - /* don't kill ourselves */ - if (f->gFile != filename) - StrAllocCopy(f->gFile, filename); - - XP_ASSERT(f->gFile != NULL); - - - if (XP_Stat(filename, &(f->laststat), xpBookmarks) != 0) { - XP_MEMSET(&(f->laststat), 0, sizeof(f->laststat)); - } - - fp = XP_FileOpen(filename, xpBookmarks, XP_FILE_READ); - - if (!fp) { - XP_FREE(buffer); - return; - } - - /* read in the first line */ - XP_FileReadLine(buffer, READ_BUFFER_SIZE, fp); - - /* DONT REQUIRE THE COOKIE FOR NOW - * - * if(XP_STRNCMP(buffer, BMLIST_COOKIE, strlen(BMLIST_COOKIE) - && XP_STRNCMP(buffer, BM_ADDR_LIST_COOKIE, strlen(BM_ADDR_LIST_COOKIE)) - * { - * TRACEMSG(("ERROR! - Hotlist cookie not found in bmlist file")); - * XP_FREE(buffer); - * return; - * } - */ - - f->undo = NULL; /* No need to log all this stuff... */ - bm_start_batch(context); - bm_refresh(context, 1, BM_LAST_CELL); - - bm_clear_alias_info(context); - - /* gBookmarks shouldn't exist yet! */ - bm_ReadFromHTML(context, fp, NULL, buffer, relative_url); - bm_SyncCount(context); - - XP_FileClose(fp); - - XP_Maphash(f->aliasTable, bm_insert_bogus_aliases, context); - - if (context->type == MWContextAddressBook) { - bm_resort_headers(context, BM_GetRoot(context)); - } - - bm_SetModified(context, FALSE); - - XP_FREE(buffer); - - bm_end_batch(context); - f->undo = undo; - UNDO_DiscardAll(undo); -} - -PUBLIC int32 -BM_SaveBookmarks(MWContext* context, const char* filename) -{ - BM_Frame* f = GETFRAME(context); - XP_File fp = NULL; - const char* bm_list_name; - XP_FileType tmptype; - char* tmpname = NULL; - XP_StatStruct curstat; - XP_Bool defaultFile; - BM_SortType enSortType = f->enSortType; - /* recognize if we're saving the current bookmarks file */ - defaultFile = (filename == NULL || (f->gFile && XP_STRCMP(filename, f->gFile) == 0)); - - CHKCONTEXT(context); - - if (filename == NULL) { - filename = f->gFile; - if (filename == NULL) return -1; /* ### */ - if (XP_Stat(filename, &curstat, xpBookmarks) != 0) { - /* The stat failed. Treat it as if the stat gave the same thing as last - time (i.e., make sure to *not* whine about the file changing from us; - most likely, the user just removed it.) */ - XP_MEMCPY(&curstat, &(f->laststat), sizeof(curstat)); - } - if (curstat.st_mtime != f->laststat.st_mtime || - curstat.st_size != f->laststat.st_size) { - if (f->gBookmarksModified) { - if (FE_Confirm(context, - XP_GetString(context->type == MWContextAddressBook ? - XP_BKMKS_ADDRESSBOOK_CONFLICT : - XP_BKMKS_BOOKMARKS_CONFLICT))) { - f->gBookmarksModified = FALSE; /* Prevent BM_ReadBookmarksFromDisk - from calling us back again. */ - BM_ReadBookmarksFromDisk(context, filename, NULL); - return 0; - } - } else { - FE_Alert(context, - XP_GetString(context->type == MWContextAddressBook ? - XP_BKMKS_ADDRESSBOOK_CHANGED : - XP_BKMKS_BOOKMARKS_CHANGED)); - BM_ReadBookmarksFromDisk(context, filename, NULL); - return 0; - } - } else { - if (!f->gBookmarksModified) return 0; /* No changes need to be saved. */ - } - } - - /* Save the natural (user arranged) sort */ - if (defaultFile && (enSortType != BM_Sort_Natural)) { - bm_SortSilent( context, BM_Sort_Natural ); - } - - bm_list_name = FE_UsersFullName(); - if (!bm_list_name) bm_list_name = FE_UsersMailAddress(); - - tmpname = FE_GetTempFileFor(NULL, filename, xpBookmarks, &tmptype); - if (!tmpname || tmpname[0] == 0) goto FAIL; - - fp = XP_FileOpen(tmpname, tmptype, XP_FILE_WRITE); - - if (!fp) goto FAIL; - - /* write cookie */ - if (context->type == MWContextBookmarks) { - if (bm_write_ok(BMLIST_COOKIE, -1, fp) < 0) goto FAIL; - } else { - if (bm_write_ok(BM_ADDR_LIST_COOKIE, -1, fp) < 0) goto FAIL; - } - if (bm_write_ok(LINEBREAK, LINEBREAK_LEN, fp) < 0) goto FAIL; - - if (bm_write_ok(XP_GetString(XP_BKMKS_AUTOGENERATED_FILE), -1, fp) < 0) { - goto FAIL; - } - if (bm_write_ok(LINEBREAK, LINEBREAK_LEN, fp) < 0) goto FAIL; - if (bm_write_ok(XP_GetString(XP_BKMKS_READ_AND_OVERWRITE), -1, fp) < 0) goto FAIL; - if (bm_write_ok(LINEBREAK, LINEBREAK_LEN, fp) < 0) goto FAIL; - if (bm_write_ok(XP_GetString(XP_BKMKS_DO_NOT_EDIT), -1, fp) < 0) goto FAIL; - if (bm_write_ok(LINEBREAK, LINEBREAK_LEN, fp) < 0) goto FAIL; - - if(context->type == MWContextBookmarks) { - if(bm_list_name) { - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_SOMEONE_S_BOOKMARKS), - "", - bm_list_name, - "" LINEBREAK); - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_SOMEONE_S_BOOKMARKS), - "

    ", - bm_list_name, - "

    \n" LINEBREAK); - } else { - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_PERSONAL_BOOKMARKS), - "", - "" LINEBREAK); - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_PERSONAL_BOOKMARKS), - "

    ", - "

    \n" LINEBREAK); - } - } else { - if(bm_list_name) { - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_SOMEONE_S_ADDRESSBOOK), - "", - bm_list_name, - "" LINEBREAK); - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_SOMEONE_S_ADDRESSBOOK), - "

    ", - bm_list_name, - "

    \n" LINEBREAK); - } else { - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_PERSONAL_ADDRESSBOOK), - "", - "" LINEBREAK); - XP_FilePrintf(fp, XP_GetString(XP_BKMKS_PERSONAL_ADDRESSBOOK), - "

    ", - "

    \n" LINEBREAK); - } - } - - bm_clear_alias_info(context); - - if (BM_GetRoot(context)) { - if (bm_WriteAsHTML(context, fp, BM_GetRoot(context), 0, FALSE) < 0) { - goto FAIL; - } - } else { - XP_TRACE(("No bmlist to write!")); - } - - if (XP_FileClose(fp) != 0) { - fp = NULL; - goto FAIL; - } - fp = NULL; - XP_FileRename(tmpname, tmptype, filename, xpBookmarks); - XP_FREE(tmpname); - tmpname = NULL; - -#ifdef XP_UNIX - /* If we write the bookmarks with at different uid or gid - * than what it had, try to change it back. - * Fix for 67572, bookmarks.html get wiped out. - */ - if (curstat.st_uid != getuid() - || curstat.st_gid != getgid()) { - chown (filename, curstat.st_uid, curstat.st_gid); - } -#endif /* XP_UNIX */ - - /* only update global mod date if we saved the current bookmk file */ - if (defaultFile) { - - if (XP_Stat(filename, &(f->laststat), xpBookmarks) != 0) { - XP_MEMSET(&(f->laststat), 0, sizeof(f->laststat)); - } - - bm_SetModified(context, FALSE); - - /* Reset the previous sort order */ - if (enSortType != BM_Sort_Natural) { - bm_SortSilent( context, enSortType ); - } - - } - - if (context->type == MWContextBookmarks) - f->errorSavingBookmarks = FALSE; - - return 1; - -FAIL: - if (fp) XP_FileClose(fp); - if (tmpname) { - XP_FileRemove(tmpname, tmptype); - XP_FREE(tmpname); - tmpname = NULL; - } - - if (context->type == MWContextAddressBook) { - FE_Alert(context, XP_GetString(XP_BKMKS_CANT_WRITE_ADDRESSBOOK)); - } - else { - if (!f->errorSavingBookmarks) { - FE_Alert(context, XP_GetString(XP_BKMKS_CANT_WRITE_BOOKMARKS)); - f->errorSavingBookmarks = TRUE; - } - } - - return -1; -} - - -/* returns the first selected item - if parent is selected, parent is returned, - otherwise the first selected child is returned - if there is no selected item following parent, - NULL is returned */ -PRIVATE BM_Entry* -bm_FirstSelectedItem_1(BM_Entry* parent) -{ - BM_Entry* child; - - XP_ASSERT(parent); - XP_ASSERT(BM_ISHEADER(parent)); - - if (BM_ISSELECTED(parent)) return parent; - - child = parent->d.header.children; - while (child) - { - if (child->flags & BM_ATTR_SELECTED) - return child; - if (child->type == BM_TYPE_HEADER) - { - BM_Entry* rv; - rv = bm_FirstSelectedItem_1(child); - if (rv) - return rv; - } - child = child->next; - } - return NULL; -} - -PUBLIC BM_Entry* -BM_FirstSelectedItem(MWContext* context) -{ - CHKCONTEXT(context); - return bm_FirstSelectedItem_1(BM_GetRoot(context)); -} - -static void -bm_InsertBySelection(MWContext* context, BM_Entry* firstSelected, - BM_Entry* newItem) -{ - BM_Frame* f = GETFRAME(context); - CHKCONTEXTVOID(context); - XP_ASSERT(firstSelected); - if (!firstSelected) firstSelected = BM_GetRoot(context); - - /* If we've selected the root node, then make sure it's not folded, so that - we will be sure to put our new item inside the root, where it belongs. */ - - if (firstSelected == BM_GetRoot(context) && BM_ISFOLDED(firstSelected)) { - BM_FoldHeader(context, firstSelected, FALSE, TRUE, FALSE); - } - - f->max_depth = 0; - - if (context->type == MWContextAddressBook && !BM_ISALIAS(newItem)) { - bm_AddChildToHeaderSorted(context, BM_GetRoot(context), newItem); - } else { - /* insert into header if it's open, else after it */ - if (BM_ISHEADER(firstSelected) && !BM_ISFOLDED(firstSelected)) { - if (context->type == MWContextBookmarks) { - BM_PrependChildToHeader(context, firstSelected, newItem); - } else { - bm_AddChildToHeaderSorted(context, firstSelected, newItem); - } - } else { - if (context->type == MWContextBookmarks) { - bm_InsertItemAfter(context, firstSelected, newItem, TRUE); - } else { - bm_AddChildToHeaderSorted(context, firstSelected->parent, newItem); - } - } - } -} - -static void -bm_BeginEditNewHeader(MWContext* context) -{ - BM_Entry* header; - BM_Entry* firstSelected; - int32 index; - - - firstSelected = BM_FirstSelectedItem(context); - if (firstSelected) - index = BM_GetIndex(context, firstSelected); - else - { - firstSelected = BM_GetRoot(context); - index = 1; - } - - header = BM_NewHeader(XP_GetString(XP_BKMKS_NEW_HEADER)); - - BM_SETFLAG(header, BM_ATTR_ISNEW); - - bm_InsertBySelection(context, firstSelected, header); - BM_SelectItem(context, header, TRUE, FALSE, TRUE); - bm_SyncCount(context); - bm_refresh(context, - context->type == MWContextBookmarks ? index + 1 : 1, - BM_LAST_CELL); - BMFE_OpenBookmarksWindow(context); - BMFE_EditItem(context, header); -} - -static void -bm_BeginEditNewUrl(MWContext* context) -{ - BM_Entry* url; - BM_Entry* firstSelected; - int32 index; - - firstSelected = BM_FirstSelectedItem(context); - if (firstSelected) - index = BM_GetIndex(context, firstSelected); - else - { - firstSelected = BM_GetRoot(context); - index = 1; - } - - if (context->type == MWContextBookmarks) { - url = BM_NewUrl(XP_GetString(XP_BKMKS_NEW_BOOKMARK), NULL, NULL, 0); - } else { - url = bm_NewAddress("", ""); - } - if (!url) return; - BM_SETFLAG(url, BM_ATTR_ISNEW); - if (context->type == MWContextBookmarks) { - bm_InsertBySelection(context, firstSelected, url); - } else { - bm_AddChildToHeaderSorted(context, BM_GetRoot(context), url); - } - BM_SelectItem(context, url, TRUE, FALSE, TRUE); - bm_SyncCount(context); - bm_refresh(context, - context->type == MWContextBookmarks ? index + 1 : 1, - BM_LAST_CELL); - BMFE_OpenBookmarksWindow(context); - BMFE_EditItem(context, url); -} - -PUBLIC void -BM_GotoBookmark(MWContext* context, BM_Entry* item) -{ - char* url = NULL; - char* target = NULL; - - CHKCONTEXTVOID(context); - - XP_ASSERT(item); - if (!item) return; - - if (item->type == BM_TYPE_ALIAS) - { - XP_ASSERT(BM_ISURL(item->d.alias.original)); - if (BM_ISURL(item->d.alias.original)) { - url = item->d.alias.original->d.url.address; - target = item->d.alias.original->d.url.target; - } - } - else if (item->type == BM_TYPE_URL) - { - url = item->d.url.address; - target = item->d.url.target; - } - - if (url) - BMFE_GotoBookmark(context, url, target); -} - -static void -bm_BeginFindBookmark(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - if (!f->gFindInfo) { - f->gFindInfo = XP_NEW_ZAP(BM_FindInfo); - if (!f->gFindInfo) return; - if (context->type == MWContextAddressBook) { - f->gFindInfo->checkNickname = TRUE; - } - f->gFindInfo->checkName = TRUE; - f->gFindInfo->checkLocation = TRUE; - f->gFindInfo->checkDescription = TRUE; - } - f->gFindInfo->lastEntry = NULL; - f->gTemporary = BMFE_OpenFindWindow(context, f->gFindInfo); -} - - -PRIVATE void -bm_SelectAliases(MWContext* context, BM_Entry* at, BM_Entry* forEntry) -{ - BM_Entry* head; - for ( ; at ; at = at->next) { - if (at->type == BM_TYPE_HEADER) { - bm_SelectAliases(context, at->d.header.children, forEntry); - } else if (BM_ISALIAS(at) && at->d.alias.original == forEntry) { - BM_SelectItem(context, at, TRUE, TRUE, TRUE); - for (head = at->parent ; head ; head = head->parent) { - if (BM_ISFOLDED(head)) { - BM_FoldHeader(context, head, FALSE, TRUE, FALSE); - } - } - } - } -} - -PUBLIC void -BM_SelectAliases(MWContext* context, BM_Entry* forEntry) -{ - CHKCONTEXTVOID(context); - XP_ASSERT(forEntry); - if (forEntry) { - bm_start_batch(context); - bm_SelectAliases(context, BM_GetRoot(context), forEntry); - bm_end_batch(context); - BMFE_ScrollIntoView(context, forEntry); - } -} - -static void -bm_CloseLastFind_1(MWContext* context, BM_Entry* entry, XP_Bool closeit) -{ - for ( ; entry ; entry = entry->next) { - if (BM_ISHEADER(entry)) { - if (entry->flags & BM_ATTR_FINDAFF) { - if (closeit) BM_FoldHeader(context, entry, TRUE, TRUE, FALSE); - BM_CLEARFLAG(entry, BM_ATTR_FINDAFF); - } - bm_CloseLastFind_1(context, entry->d.header.children, closeit); - } - } -} - - -/* Close any headers that we may have opened last time we did a find. */ -static void -bm_CloseLastFind(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - if (f->unfoldedForFind) { - f->unfoldedForFind = FALSE; /* Do this first, to not confuse - BM_FoldHeader(). */ - bm_CloseLastFind_1(context, BM_GetRoot(context), TRUE); - } -} - -/* Forget about any headers that were opened last time we did a find; leave - things the way they are now. */ -static void -bm_CancelLastFind(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - if (f->unfoldedForFind) { - f->unfoldedForFind = FALSE; - bm_CloseLastFind_1(context, BM_GetRoot(context), FALSE); - } -} - -static void -bm_OpenNewFind(MWContext* context, BM_Entry* entry) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* head; - XP_Bool found = FALSE; - if (!entry) return; - bm_CloseLastFind(context); - for (head = entry->parent ; head ; head = head->parent) { - if (BM_ISFOLDED(head)) { - BM_FoldHeader(context, head, FALSE, TRUE, FALSE); - BM_SETFLAG(head, BM_ATTR_FINDAFF); - found = TRUE; - } - } - f->unfoldedForFind = found; /* Must set last, to not confuse - BM_FoldHeader. */ -} - - -void -BM_DoFindBookmark(MWContext* context, BM_FindInfo* findInfo) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* found = NULL; - BM_Entry* startAt = NULL; - XP_Bool unfoldedForFind; - - /* If no find string is specified, return. */ - if (findInfo->textToFind == NULL) - return; - - bm_CloseLastFind(context); - - if (findInfo->lastEntry) { - startAt = bm_GetNextSpanningWrapping(context, findInfo->lastEntry); - } else { - startAt = BM_GetRoot(context); - } - found = bm_DoFindBookmark_1(context, startAt, findInfo); - - if (found) { - bm_CloseLastFind(context); - bm_OpenNewFind(context, found); - unfoldedForFind = f->unfoldedForFind; - f->unfoldedForFind = FALSE; /* Don't confuse BM_SelectItem */ - BM_SelectItem(context, found, TRUE, FALSE, TRUE); - bm_flush_updates(context); - BMFE_ScrollIntoView(context, found); - f->unfoldedForFind = unfoldedForFind; - } else { - FE_Alert(context, XP_GetString(XP_BKMKS_NOT_FOUND)); - } - findInfo->lastEntry = found; -} - - -static void -bm_parse_mailto(const char* url, char** name, char** addr) -{ - char* ptr; - char* buf; - int32 L; - if (name) *name = NULL; - if (addr) *addr = NULL; - if (strncasecomp(url, "mailto:?to=", 11) != 0) return; - url += 11; - ptr = XP_STRCHR(url, '&'); - L = (ptr ? (ptr - url) : XP_STRLEN(url)); - buf = (char *) XP_ALLOC(L+1); - if (!buf) return; - XP_MEMCPY (buf, url, L); - buf[L] = 0; - buf = NET_UnEscape(buf); - -#if 0 - MSG_ParseRFC822Addresses(buf, name, addr); -#else - /* We need to do it this way to get msg_quote_phrase_or_addr() to be - called on the names. Perhaps that function should just be exported... - */ -#ifdef MOZ_MAIL_NEWS - if (name) *name = MSG_ExtractRFC822AddressNames (buf); - if (addr) *addr = MSG_ExtractRFC822AddressMailboxes (buf); -#endif /* MOZ_MAIL_NEWS */ -#endif - - XP_FREE(buf); -} - -BM_Entry* -BM_FindAddress(MWContext* context, const char* url) -{ - char* address; - BM_Entry* result = NULL; - BM_Entry* entry; - CHKCONTEXT(context); - XP_ASSERT(url); - if (!url) return NULL; - bm_parse_mailto(url, NULL, &address); - if (!address) return NULL; - - /* Takes advantage of the fact that addressbook always has all address - entries as children of the root header. */ - for (entry = BM_GetRoot(context)->d.header.children; - entry; - entry = entry->next) { - if (BM_ISADDRESS(entry) && - XP_STRCMP(entry->d.address.address, address) == 0) { - result = entry; - break; - } - } - XP_FREE(address); - return result; -} - - -void -BM_EditAddress(MWContext* context, const char* url) -{ - BM_Entry* entry; - CHKCONTEXTVOID(context); - XP_ASSERT(url); - if (!url) return; - bm_start_batch(context); - entry = BM_FindAddress(context, url); - if (!entry) { - char* name; - char* address; - bm_parse_mailto(url, &name, &address); /* Parsing a second time. Oh, - well. ### */ - if (!name) name = XP_STRDUP(""); - if (!address) address = XP_STRDUP(""); - if (!name || !address) goto FAIL; - - entry = bm_NewAddress(name, address); - XP_FREE(name); - XP_FREE(address); - if (!entry) goto FAIL; - BM_SETFLAG(entry, BM_ATTR_ISNEW); - bm_AddChildToHeaderSorted(context, BM_GetRoot(context), entry); - BM_SelectItem(context, entry, TRUE, FALSE, TRUE); - bm_SyncCount(context); - bm_refresh(context, 1, BM_LAST_CELL); - } - BMFE_OpenBookmarksWindow(context); - BMFE_EditItem(context, entry); -FAIL: - bm_end_batch(context); -} - - - - -/* - * Utilities to fuss with bookmarks in a drag and drop evnironment - * - * There are two user visible functions in this file: - * - * Allocate and return a string that contains the text representation of - * a list of bookmarks entries (including headers and their contents). - * The caller is responsible for freeing the string. The total length of - * the block that was allocated is returned in lTotalLen. List is the - * list of pointers to bookmarks items that are selected, iCount is the - * length of that list. - * This function has two modes of operation, a short mode and a long mode. - * If bLongFormat == FALSE the returned block just has URLs separated by - * \n's. If bLongFormat == TRUE all of the information needed to recreate - * the bookmarks item is included - * - -PUBLIC char * -BM_ConvertSelectionsToBlock(BM_Entry ** list, - int iCount, - int bLongFormat, - int32 * lTotalLen); - * - * ------------------------ - * - * Take a block of memory formatted by BM_ConvertSelectionsToBlock and insert - * the items it represents into the bookmarks following 'item'. If item is - * NULL insert at the beginning of the bookmarks. bLongFormat has the same - * meaning as in BM_ConvertSelectionsToBlock(). lTotalLen should be the - * length of the block of memory --- I'm not sure if this is necessary - * because on Windows at least the value we get back is meaningless, so - * this function just ignores it. - * -PUBLIC void -BM_InsertBlockAt(char * pOriginalBlock, - BM_Entry * item, - int bLongFormat, - int32 lTotalLen); - * - */ - - - -#define TEXT_INDENT 3 - -/* - * Measure a boring URL bookmarks entry and return the length in bytes - * - * Short format: - * " item->address\n" - * where there are nIndent number of spaces before the item - * - * Long format: - * uint16 type - * char item->name\n - * char item->address\n - * time_t addition_date - * time_t last_visit_date - * time_t last_modified_date - * char item->description\0 - * - * The item->description field is *NOT* \n terminated since it might - * be a multi-line string and is therefore \0 terminated - */ -PRIVATE int32 -bm_measure_URL(BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - int32 iSpace = 0; - - if (!item) - return 0; - - XP_ASSERT(BM_ISURL(item)); - - /* NO. We cannot check for ISSELECTED here. We could be called - * by bm_measure_Header which was selected although we by - * ourselves are not selected. - * - * if (! BM_ISSELECTED(item)) - * return 0; - */ - - if (bLongFormat) - { - iSpace += sizeof(item->type) + - sizeof(item->addition_date) + - sizeof(item->d.url.last_visit) + - sizeof(item->d.url.last_modified); - - if (item->name) - iSpace += XP_STRLEN(item->name); - iSpace++; /* +1 for '\n' */ - if (item->description) - iSpace += XP_STRLEN(item->description); - iSpace++; /* +1 for '\0' */ - } - else - { - /* space indentation and '\n' terminator */ - iSpace = nIndent; - } - - /* the address appears in both formats */ - if (item->d.url.address) - iSpace += (XP_STRLEN(item->d.url.address) + 1); /* +1 for '\n' */ - - return (iSpace); -} - -PRIVATE int32 -bm_measure_Alias(BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - int32 iSpace = 0; - - XP_ASSERT(BM_ISALIAS(item)); - - if (bLongFormat) - { - iSpace += sizeof(item->type); - } - return (iSpace); -} - -/* - * Measure a separator entry and return the length in bytes - * - * Short format: - * " -------------\0" - * where there are nIndent number of spaces before the 13 -'s - * - * Long format: - * uint16 type - * - */ -PRIVATE int32 -bm_measure_Separator(BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - int32 iSpace = 0; - - if (!item) - return 0; - - XP_ASSERT(BM_ISSEPARATOR(item)); - - if (bLongFormat) - { - iSpace += sizeof(item->type); - } - else - { - /* space indentation and '\n' terminator */ - iSpace = nIndent; - iSpace += 13; - iSpace ++ /* for '\n' */; - } - - return (iSpace); -} - -/* - * Measure a header entry and all its children - * - * Short format: - * " item->name\n" - * " child1->address\n" - * " child2->address\n" - * where there are nIndent number of spaces before the item and - * TEXT_INDENT spaces between levels - * - * Long format: - * uint16 type - * char item->name\n - * time_t addition_date - * uint32 number of children - * char item->description\0 - * - * The item->description field is *NOT* \n terminated since it might - * be a multi-line string and is therefore \0 terminated. Note that - * the address field is *NOT* written for headers since its it meaningless - */ -PRIVATE int32 -bm_measure_Header(BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - int32 iSpace = 0; - BM_Entry* child = NULL; - - if (!item) - return 0; - - XP_ASSERT(BM_ISHEADER(item)); - - /* if the header is selected, count it as well */ - if (bLongFormat) - { - iSpace += sizeof(item->type) + - sizeof(item->addition_date) + - sizeof(item->d.header.childCount); - - if (item->description) - iSpace += XP_STRLEN(item->description); - iSpace++; /* for \0 */ - } - else - { - /* space indentation and '\n' terminator */ - iSpace = nIndent; - } - - /* the name appears in both formats */ - if (item->name) - iSpace += XP_STRLEN(item->name); - iSpace ++; /* for \n terminator */ - - /* measure the amount of space taken up by this item's children */ - child = item->d.header.children; - while (child) - { - switch (child->type) - { - case BM_TYPE_URL: - iSpace += bm_measure_URL(child, bLongFormat, nIndent + TEXT_INDENT); - break; - case BM_TYPE_ALIAS: - iSpace += bm_measure_Alias(child, bLongFormat, nIndent + TEXT_INDENT); - break; - case BM_TYPE_HEADER: - iSpace += bm_measure_Header(child, bLongFormat, nIndent + TEXT_INDENT); - break; - case BM_TYPE_SEPARATOR: - iSpace += bm_measure_Separator(child, bLongFormat, nIndent + TEXT_INDENT); - break; - default: - break; - } - child = child->next; - } - - return iSpace; -} - -/* - * Write out a separator bookmarks entry. - */ -PRIVATE char* -bm_write_Separator(char* buffer, BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - int32 iLen; - BM_Type type; - - if (!item || !buffer) - return buffer; - - XP_ASSERT(BM_ISSEPARATOR(item)); - - if (bLongFormat) - { - /* copy the type */ - type = item->type; - iLen = sizeof(BM_Type); - XP_MEMCPY(buffer, &type, iLen); - buffer += iLen; - } - else - { - XP_MEMSET(buffer, ' ', nIndent); - buffer += nIndent; - XP_MEMSET(buffer, '-', 13); - buffer += 13; - *buffer++ = '\0'; - } - - return buffer; -} - -/* - * Write out a boring URL bookmarks entry. See comment at the top of - * bm_measure_URL for the format used. Assume we start writing at - * the start of the buffer passed in. Return a pointer to where the - * buffer ends when we get done. - */ -PRIVATE char* -bm_write_URL(char* buffer, BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - int32 iLen; - BM_Date lVal; - BM_Type type; - - if (!item || !buffer) - return buffer; - - XP_ASSERT(BM_ISURL(item) || BM_ISALIAS(item)); - - if (bLongFormat) - { - /* copy the type */ - type = item->type; - iLen = sizeof(BM_Type); - XP_MEMCPY(buffer, &type, iLen); - buffer += iLen; - - if (BM_ISALIAS(item)) - return buffer; - - /* copy the name */ - if (item->name) - { - iLen = XP_STRLEN(item->name); - XP_MEMCPY(buffer, item->name, iLen); - buffer += iLen; - } - /* put the \n terminator on */ - *buffer++ = '\n'; - - /* copy the address */ - if (item->d.url.address) - { - iLen = XP_STRLEN(item->d.url.address); - XP_MEMCPY(buffer, item->d.url.address, iLen); - buffer += iLen; - } - /* put the \n terminator on */ - *buffer++ = '\n'; - - /* addition date */ - lVal = item->addition_date; - iLen = sizeof(BM_Date); - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* last visit date */ - lVal = item->d.url.last_visit; - iLen = sizeof(BM_Date); - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* last modified date */ - lVal = item->d.url.last_modified; - iLen = sizeof(BM_Date); - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* copy the description */ - if (item->description) - { - iLen = XP_STRLEN(item->description); - XP_MEMCPY(buffer, item->description, iLen); - buffer += iLen; - } - /* put the \n terminator on */ - *buffer++ = '\0'; - - } - else if (BM_ISURL(item)) - { - XP_MEMSET(buffer, ' ', nIndent); - buffer += nIndent; - - if(item->d.url.address) - { - XP_STRCPY(buffer, item->d.url.address); - buffer += XP_STRLEN(item->d.url.address); - } - *buffer++ = '\n'; - } - - return buffer; -} - - -/* - * Write out a bookmarks header entry. See comment at the top of - * bm_measure_Header for the format used. Assume we start writing at - * the start of the buffer passed in. Return a pointer to where the - * buffer ends when we get done. - */ -PRIVATE char* -bm_write_Header(char* buffer, BM_Entry* item, XP_Bool bLongFormat, int nIndent) -{ - long iLen; - BM_Date lVal; - BM_Type type; - uint32 children; - BM_Entry* child = NULL; - - if (!item || !buffer) - return buffer; - - XP_ASSERT(BM_ISHEADER(item)); - - if (bLongFormat) - { - /* copy the type */ - type = item->type; - iLen = sizeof(BM_Type); - XP_MEMCPY(buffer, &type, iLen); - buffer += iLen; - - /* copy the name */ - if (item->name) - { - iLen = XP_STRLEN(item->name); - XP_MEMCPY(buffer, item->name, iLen); - buffer += iLen; - } - /* put the \n terminator on */ - *buffer++ = '\n'; - - /* addition date */ - lVal = item->addition_date; - iLen = sizeof(BM_Date); - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* number of children */ - children = item->d.header.childCount; - iLen = sizeof(uint32); - XP_MEMCPY(buffer, &children, iLen); - buffer += iLen; - - /* copy the description */ - if (item->description) - { - iLen = XP_STRLEN(item->description); - XP_MEMCPY(buffer, item->description, iLen); - buffer += iLen; - } - /* put the \n terminator on */ - *buffer++ = '\0'; - - } - else - { - XP_MEMSET(buffer, ' ', nIndent); - buffer += nIndent; - if(item->name) - { - XP_STRCPY(buffer, item->name); - buffer += XP_STRLEN(item->name); - } - *buffer++ = '\n'; - } - - child = item->d.header.children; - while (child) - { - switch (child->type) - { - case BM_TYPE_URL: - case BM_TYPE_ALIAS: - buffer = bm_write_URL(buffer, child, bLongFormat, nIndent + TEXT_INDENT); - break; - case BM_TYPE_HEADER: - buffer = bm_write_Header(buffer, child, bLongFormat, nIndent + TEXT_INDENT); - break; - case BM_TYPE_SEPARATOR: - buffer = bm_write_Separator(buffer, child, bLongFormat, nIndent + TEXT_INDENT); - break; - default: - break; - } - child = child->next; - } - - return buffer; -} - -/* - * Take a separator packed in a block the way bm_write_Separator packs it. - * Return the new item if we created one - */ -PRIVATE BM_Entry* -bm_read_Separator(char* buffer, XP_Bool bLongFormat, int32* lBytesEaten) -{ - BM_Entry* new_item = NULL; - - if (!buffer) - return NULL; - - if (bLongFormat) - { - /* for now the separator written has only the type. - since that was already read in before this was clled - we have nothing to eat here */ - new_item = bm_NewSeparator(); - *lBytesEaten = 0; - } - else - { - /* we should really strip leading whitespace */ - new_item = bm_NewSeparator(); - *lBytesEaten = XP_STRLEN(buffer) + 1; - } - - return new_item; -} - -/* - * Take a URL packed in a block the way bm_write_URL packs it. - * Return the new item if we created one - */ -PRIVATE BM_Entry* -bm_read_url_long(char* buffer, XP_Bool bLongFormat, int32* lBytesEaten) -{ - BM_Entry* new_item = NULL; - - if (!buffer) - return NULL; - - if (bLongFormat) - { - BM_Date addition; - BM_Date visit; - BM_Date modified; - - /* get the name */ - char* name = buffer; - char* address = strchr(name, '\n'); - char* description = NULL; - char* ptr; - if (!address) - return NULL; - *address++ = '\0'; - - /* get the address */ - ptr = strchr(address, '\n'); - if(!ptr) - return NULL; - *ptr++ = '\0'; - - /* addition date */ - XP_MEMCPY(&addition, ptr, sizeof(BM_Date)); - ptr += sizeof(BM_Date); - - /* visiting date */ - XP_MEMCPY(&visit, ptr, sizeof(BM_Date)); - ptr += sizeof(BM_Date); - - /* modified date */ - XP_MEMCPY(&modified, ptr, sizeof(BM_Date)); - ptr += sizeof(BM_Date); - - /* get the description (it should be NULL terminated) */ - description = ptr; - - /* we should really strip leading whitespace */ - new_item = BM_NewUrl(name, address, 0, visit); - new_item->addition_date = addition; - new_item->description = XP_STRDUP(description); - new_item->d.url.last_modified = modified; - *lBytesEaten = XP_STRLEN(description) + (description - buffer) + 1; - - } - else - { - char* end = strchr(buffer, '\n'); - - /* if there was a return NULL terminate the current string */ - if (end) - *end++ = '\0'; - - /* we should really strip leading whitespace */ - new_item = BM_NewUrl(buffer, buffer, 0, 0); - new_item->addition_date = XP_TIME(); - *lBytesEaten = XP_STRLEN(buffer) + 1; - } - - return new_item; -} - -/* - * Take a header and children packed in a block the way bm_write_Header - * packs it. Return the new header item if we created one - */ -PRIVATE BM_Entry* -bm_read_header_long(MWContext* context, char* buffer, XP_Bool bLongFormat, - int32* lBytesEaten) -{ - uint32 kids = 0; - BM_Type type; - BM_Entry* new_item = NULL; - BM_Entry* kid = NULL; - char* name = NULL; - char* ptr = NULL; - char* description = NULL; - BM_Date addition; - uint32 i; - int32 lEat; - - if (!buffer) - return NULL; - - /* can only read long format headers */ - if (bLongFormat) - { - /* get the name */ - name = buffer; - ptr = strchr(name, '\n'); - description = NULL; - if (!ptr) - return NULL; - - /* skip over the \n but change it to a \0 so strcpy() will work */ - *ptr++ = '\0'; - - /* addition date */ - XP_MEMCPY(&addition, ptr, sizeof(BM_Date)); - ptr += sizeof(BM_Date); - - /* number of children to read */ - XP_MEMCPY(&kids, ptr, sizeof(uint32)); - ptr += sizeof(uint32); - - /* get the description (it should be NULL terminated) */ - description = ptr; - - /* we should really strip leading whitespace */ - new_item = BM_NewHeader(name); - new_item->addition_date = addition; - new_item->description = XP_STRDUP(description); - *lBytesEaten = XP_STRLEN(description) + (description - buffer) + 1; - - /* handle all of the kids now */ - if (kids) - { - buffer += *lBytesEaten; - - for (i = 0; i < kids; i++) - { - /* determine the type of the next entry */ - XP_MEMCPY(&type, buffer, sizeof(BM_Type)); - buffer += sizeof(BM_Type); - *lBytesEaten += sizeof(BM_Type); - - switch (type) - { - case BM_TYPE_URL: - kid = bm_read_url_long(buffer, bLongFormat, &lEat); - *lBytesEaten += lEat; - buffer += lEat; - bm_AppendChildToHeader(context, new_item, kid); - break; - case BM_TYPE_ALIAS: - break; - case BM_TYPE_HEADER: - kid = bm_read_header_long(context, buffer, bLongFormat, &lEat); - *lBytesEaten += lEat; - buffer += lEat; - bm_AppendChildToHeader(context, new_item, kid); - break; - case BM_TYPE_SEPARATOR: - kid = bm_read_Separator(buffer, bLongFormat, &lEat); - *lBytesEaten += lEat; - buffer += lEat; - bm_AppendChildToHeader(context, new_item, kid); - break; - case 12345: - /* Ah ha! this is the end marker we wrote. Something - terribly wrong here. We shouldn't have hit this - before we read all the kids in. */ - abort(); - break; - default: - /* bogus type. Who knows whats going on. Just quit and get out */ - break; - } - - } - - } - } - - return new_item; -} - -PRIVATE int32 -bm_measure(BM_Entry* root, XP_Bool bLongFormat, int32 indent) -{ - int32 iSpace = 0; - BM_Entry* child; - - XP_ASSERT(root); - XP_ASSERT(BM_ISHEADER(root)); - - child = root->d.header.children; - - while (child) - { - switch (child->type) - { - case BM_TYPE_URL: - if (BM_ISSELECTED(child)) - iSpace += bm_measure_URL(child, bLongFormat, indent); - break; - case BM_TYPE_ALIAS: - iSpace += bm_measure_Alias(child, bLongFormat, indent + TEXT_INDENT); - break; - case BM_TYPE_HEADER: - if (BM_ISSELECTED(child)) - iSpace += bm_measure_Header(child, bLongFormat, indent); - else - if (! BM_ISFOLDED(child)) - iSpace += bm_measure(child, bLongFormat, indent); - break; - case BM_TYPE_SEPARATOR: - if (BM_ISSELECTED(child)) - iSpace += bm_measure_Separator(child, bLongFormat, indent); - break; - } - child = child->next; - } - return iSpace; -} - -PRIVATE char* -bm_write(char* buffer, BM_Entry* root, XP_Bool bLongFormat, int32 indent) -{ - BM_Entry* child; - - XP_ASSERT(root); - XP_ASSERT(BM_ISHEADER(root)); - - child = root->d.header.children; - - while (child) - { - switch (child->type) - { - case BM_TYPE_URL: - case BM_TYPE_ALIAS: - if (BM_ISSELECTED(child)) - buffer = bm_write_URL(buffer, child, bLongFormat, indent); - break; - - case BM_TYPE_HEADER: - if (BM_ISSELECTED(child)) - buffer = bm_write_Header(buffer, child, bLongFormat, indent); - else - if (! BM_ISFOLDED(child)) - buffer = bm_write(buffer, child, bLongFormat, indent); - break; - case BM_TYPE_SEPARATOR: - if (BM_ISSELECTED(child)) - buffer = bm_write_Separator(buffer, child, bLongFormat, indent); - break; - } - child = child->next; - } - return buffer; -} - -/* - * Allocate and return a string that contains the text representation of - * a list of bookmarks entries from specified selections in a History window. - * The caller is responsible for freeing the string - */ -PUBLIC char * -BM_ClipCopyHistorySelection( void *pHistCsr, uint32 *pSelections, int iCount, int *pSize, XP_Bool bLongFormat ) -{ - int i, iLen, iSize = 0; - uint16 marker; - char * pStorage = NULL; - char * pStgCsr = NULL; - BM_Entry * pBM = NULL; - BM_Entry * pPrevBM = NULL; - BM_Entry * pCsr = NULL; - BM_Entry * pBMList = NULL; - - if( !pHistCsr || !pSelections || iCount <= 0 ) - { - return NULL; - } - - /* - * Build the list of BM_Entrys and calc the total size - */ - for( i = 0; i < iCount; i++ ) - { - gh_HistEntry *pHistEntry = GH_GetRecord( pHistCsr, pSelections[i] ); - if( !pHistEntry ) - { - /* In case history file was somehow compromised */ - continue; - } - - /* - * Map the gh_HistEntry to the BM_Entry - */ - - pBM = (BM_Entry *)XP_ALLOC( sizeof(BM_Entry) ); - XP_MEMSET( pBM, 0, sizeof(BM_Entry) ); - if( !pPrevBM ) - { - pBMList = pBM; - } - else - { - pPrevBM->next = pBM; - } - pPrevBM = pBM; - - /* type */ - pBM->type = BM_TYPE_URL; - - if( bLongFormat ) - { - /* name */ - iLen = pHistEntry->pszName ? XP_STRLEN( pHistEntry->pszName )+1 : 0; - pBM->name = iLen ? (char *)XP_ALLOC( iLen*sizeof(char) ) : NULL; - if( iLen ) - { - XP_STRCPY( pBM->name, pHistEntry->pszName ); - } - - /* addition date */ - time( &pBM->addition_date ); - - /* last visit date */ - pBM->d.url.last_visit = pHistEntry->last_accessed; - - /* last modified */ - time( &pBM->d.url.last_modified ); - - /* description */ - pBM->description = NULL; - } - - /* address */ - iLen = pHistEntry->address ? XP_STRLEN( pHistEntry->address )+1 : 0; - pBM->d.url.address = iLen ? (char *)XP_ALLOC( iLen*sizeof(char) ) : NULL; - if( iLen ) - { - XP_STRCPY( pBM->d.url.address, pHistEntry->address ); - } - - - /* - * Calc the size - */ - - iSize += bm_measure_URL( pBM, bLongFormat, 0 ); - } - - if( bLongFormat ) - { - iSize += sizeof(uint16); - } - - /* Leave room for the termination character */ - iSize++; - - #ifdef XP_WIN16 - if( (uint16)iSize > (uint16)(32*1024-1) ) - { - return NULL; - } - #endif - - /* Allocate the storage */ - pStorage = pStgCsr = (char *)XP_ALLOC( iSize*sizeof(char) ); - if( !pStorage ) - { - return NULL; - } - - /* Copy the bookmarks to the storage */ - pCsr = pBMList; - while( pCsr ) - { - pStgCsr = bm_write_URL( pStgCsr, pCsr, bLongFormat, 0 ); - - pPrevBM = pCsr; - - pCsr = pCsr->next; - - /* Free the entry */ - pPrevBM->next = NULL; - bm_ShallowFreeEntry( pPrevBM ); - } - - if (bLongFormat) - { - /* Write the end-of-list marker */ - marker = 12345; - XP_MEMCPY( pStgCsr, &marker, 2 ); - pStgCsr += sizeof(uint16); - } - - /* End the string */ - *pStgCsr++ = '\0'; - *pSize = (pStgCsr - pStorage); - - return pStorage; -} - - -/* - * Allocate and return a string that contains the text representation of - * a list of bookmarks entries (including headers and their contents). - * The caller is responsible for freeing the string - */ -PUBLIC char* -BM_ConvertSelectionsToBlock(MWContext* context, - XP_Bool bLongFormat, - int32* lTotalLen) -{ - uint16 marker; - int32 iSpace = 0; - char* pString; - char* pOriginal; - - BM_Entry* tmp; - - CHKCONTEXT(context); - - tmp = BM_GetRoot(context); - iSpace = bm_measure(tmp, bLongFormat, 0); - - /* leave room for end of list marker */ - if (bLongFormat) - iSpace += sizeof(uint16); - - /* leave room for the termination character */ - iSpace++; - -#ifdef XP_WIN16 - if (iSpace > 32000) - return NULL; -#endif - - /* allocate the string */ - pOriginal = pString = (char*)XP_ALLOC(iSpace * sizeof(char)); - if (!pString) - return NULL; - - /* Make a big string */ - pString = bm_write(pString, tmp, bLongFormat, 0); - - /* stick the end of list marker on so that when we are decoding this */ - /* block we know when we are done */ - if (bLongFormat) - { - marker = 12345; - XP_MEMCPY(pString, &marker, 2); - pString += sizeof(uint16); - } - - /* end the string and return the total length to our caller */ - *pString++ = '\0'; - *lTotalLen = (pString - pOriginal); - return pOriginal; -} - - -/* - * Take a block of memory formatted by BM_ConvertSelectionsToBlock and insert - * the items it represents into the bookmarks following 'item'. If item is - * NULL insert at the beginning of the bookmarks. - */ -PUBLIC void -BM_InsertBlockAt(MWContext* context, - char* pOriginalBlock, - BM_Entry* addTo, - XP_Bool bLongFormat, - int32 lTotalLen) -{ - BM_Type type; - int32 lBytesEaten = 0; /* total number of bytes eaten */ - int32 lEat; /* number of bytes eaten on this item */ - char* pCurrentPos; - char* pBlock; - BM_Entry* tmp; - BM_Entry* item; - XP_Bool first = TRUE; - - CHKCONTEXTVOID(context); - if (!pOriginalBlock) return; - - if (addTo == NULL) addTo = BM_GetRoot(context); - - /* make a copy of the string we can write into */ - pCurrentPos = pBlock = (char*) XP_ALLOC(lTotalLen + 1); - if (!pBlock) return; - - bm_start_batch(context); - /* copy the data over and make sure we are NULL terminated to make life - easier */ - XP_MEMCPY(pBlock, pOriginalBlock, lTotalLen); - pBlock[lTotalLen] = '\0'; - - /* long format can have all kinds of different types of things in it */ - if (bLongFormat) { - while (lBytesEaten < lTotalLen) { - /* determine the type of the next entry */ - XP_MEMCPY(&type, pCurrentPos, sizeof(BM_Type)); - pCurrentPos += sizeof(BM_Type); - lBytesEaten += sizeof(BM_Type); - - item = NULL; - - switch (type) { - case BM_TYPE_URL: - item = bm_read_url_long(pCurrentPos, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - break; - - case BM_TYPE_ALIAS: - break; - - case BM_TYPE_HEADER: - item = bm_read_header_long(context, pCurrentPos, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - break; - - case BM_TYPE_SEPARATOR: - item = bm_read_Separator(pCurrentPos, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - break; - - case 12345: - /* Ah ha! this is the end marker we wrote! remember... */ - XP_ASSERT((lBytesEaten+1) == lTotalLen); - break; - default: - /* bogus type. Who knows whats going on. Just quit and - get out */ - goto GETOUT; - - break; - } - if (item) { - if (first && BM_ISHEADER(addTo) && !BM_ISFOLDED(addTo)) { - /* Adding inside a folder as first child. */ - BM_PrependChildToHeader(context, addTo, item); - } else { - bm_InsertItemAfter(context, addTo, item, FALSE); - } - addTo = item; - first = FALSE; - } - } - } else { - item = NULL; - /* short format is just a list of URLs separated by \n's */ - while (lBytesEaten < lTotalLen) { - item = bm_read_url_long(pCurrentPos, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - - if (item) { - tmp = addTo->next; - addTo->next = item; - item->next = tmp; - addTo = item; - } - /* if we just walked over a \0 we are done */ - if (pOriginalBlock[lBytesEaten - 1] == '\0') { - lBytesEaten = lTotalLen; - } - } - } - -GETOUT: - /* mark the bookmark list as changed and clean up */ - bm_SetModified(context, TRUE); - XP_FREE(pBlock); - bm_end_batch(context); -} - - - - -static void -bm_make_alias(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_Entry* newAlias; - int32 index; - - CHKCONTEXTVOID(context); - - if (BM_ISURL(entry)) { - newAlias = bm_NewAlias(entry); - if (!newAlias) return; - - bm_InsertItemAfter(context, entry, newAlias, FALSE); - - index = BM_GetIndex(context, newAlias); - if (index > 0) { - bm_refresh(context, index, BM_LAST_CELL); - } - } -} - -PUBLIC void -BM_MakeAliases(MWContext* context) -{ - CHKCONTEXTVOID(context); - bm_start_batch(context); - BM_EachSelectedEntryDo(context, bm_make_alias, NULL); - bm_SyncCount(context); - bm_end_batch(context); -} - - -BM_Entry* -BM_GetAliasOriginal(BM_Entry* entry) -{ - XP_ASSERT(BM_ISALIAS(entry)); - return BM_ISALIAS(entry) ? entry->d.alias.original : NULL; -} - - -static XP_Bool -bm_SelectionIsContiguous_1(MWContext* context, BM_Entry* entry, - XP_Bool* started, XP_Bool* finished) -{ - XP_Bool result; - for (; entry ; entry = entry->next) { - if (BM_ISSELECTED(entry)) { - if (*finished) return FALSE; - *started = TRUE; - } else { - if (*started) *finished = TRUE; - } - if (BM_ISHEADER(entry) && !BM_ISFOLDED(entry)) { - result = bm_SelectionIsContiguous_1(context, entry->d.header.children, - started, finished); - if (!result) return result; - } - } - return TRUE; -} - -static XP_Bool -bm_SelectionIsContiguous(MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - XP_Bool started = FALSE; - XP_Bool finished = FALSE; - if (f->gSelectionCount < 0) bm_SyncSelection(context); - if (f->gSelectionCount < 2) return TRUE; - return bm_SelectionIsContiguous_1(context, BM_GetRoot(context), - &started, &finished); -} - -XP_Bool BM_FindCommandStatus(MWContext* context, BM_CommandType command) -{ - BM_Frame* f = GETFRAME(context); - int32 length; - - CHKCONTEXT(context); - - if (f->gSelectionCount < 0) bm_SyncSelection(context); - - switch (command) { - case BM_Cmd_Invalid: - return FALSE; - - case BM_Cmd_Open: /**/ - case BM_Cmd_ImportBookmarks: - case BM_Cmd_SaveAs: /**/ - return TRUE; - - case BM_Cmd_Close: /**/ - return TRUE; - - case BM_Cmd_Undo: - return UNDO_CanUndo(f->undo); - case BM_Cmd_Redo: - return UNDO_CanRedo(f->undo); - - case BM_Cmd_Cut: - case BM_Cmd_Copy: - case BM_Cmd_Delete: - return (f->gSelectionCount > 0); - - case BM_Cmd_Paste: - return BMFE_GetClipContents(context, &length) ? TRUE : FALSE; - break; - - - case BM_Cmd_SelectAllBookmarks: /**/ - return TRUE; - - case BM_Cmd_Find: - return TRUE; - - case BM_Cmd_FindAgain: - return ((f->gFindInfo != NULL) && (f->gFindInfo->textToFind != NULL)); - - case BM_Cmd_BookmarkProps: /**/ - return (f->gSelectionCount == 1 && - !(f->gSelectionMask & BM_TYPE_SEPARATOR)); - - case BM_Cmd_Sort_Name: - case BM_Cmd_Sort_Name_Asc: - case BM_Cmd_Sort_Address: - case BM_Cmd_Sort_Address_Asc: - case BM_Cmd_Sort_AddDate: - case BM_Cmd_Sort_AddDate_Asc: - case BM_Cmd_Sort_LastVisit: - case BM_Cmd_Sort_LastVisit_Asc: - case BM_Cmd_Sort_Natural: - if (f->gSelectionCount == 0) return FALSE; - if (f->gSelectionCount == 1) { - return f->gSelectionMask == BM_TYPE_HEADER; - } - return bm_SelectionIsContiguous(context); - - case BM_Cmd_InsertBookmark: - case BM_Cmd_InsertHeader: - return TRUE; - - case BM_Cmd_InsertSeparator: - return context->type == MWContextBookmarks; - - case BM_Cmd_GotoBookmark: - if (context->type == MWContextBookmarks) { - return (f->gSelectionCount == 1 && - (f->gSelectionMask & (BM_TYPE_URL | BM_TYPE_ALIAS))); - } else { - return f->gSelectionCount > 0; - } - - case BM_Cmd_MakeAlias: - return (f->gSelectionCount == 1 && - (f->gSelectionMask & BM_TYPE_URL)); - - case BM_Cmd_SetAddHeader: - return (context->type == MWContextBookmarks && - f->gSelectionCount == 1 && - (f->gSelectionMask & BM_TYPE_HEADER) && - BM_FirstSelectedItem(context) != f->addheader); - - case BM_Cmd_SetMenuHeader: - return (context->type == MWContextBookmarks && - f->gSelectionCount == 1 && - (f->gSelectionMask & BM_TYPE_HEADER) && - BM_FirstSelectedItem(context) != f->menuheader); - - default: - XP_ASSERT(0); - break; - } - return FALSE; -} - -static void -bm_open_file(MWContext* context, char* newFile, void* closure) -{ - if (newFile) { -#ifdef XP_WIN - BMFE_ChangingBookmarksFile(); -#endif - - BM_ReadBookmarksFromDisk(context, newFile, NULL); - -#ifdef XP_WIN - BMFE_ChangedBookmarksFile(); -#endif - - XP_FREE(newFile); - } -} - - -/* LI_STUFF give li the ability to open a new bookmarks file */ -void -BM_Open_File(MWContext* context, char* newFile) -{ - bm_open_file(context, newFile, NULL); -} - - -static void -bm_import_file(MWContext* context, char* newFile, void* closure) -{ - BM_Frame* f = GETFRAME(context); - bm_start_batch(context); - UNDO_DiscardAll(f->undo); - if (newFile) { - BM_Entry* oldroot = f->gBookmarks; - BM_Entry* oldmenuheader = f->menuheader; - BM_Entry* oldaddheader = f->addheader; - BM_Entry* newroot; - BM_Entry* entry; - BM_Entry* next; - char* oldfile = NULL; - XP_StatStruct savedStat; - - if (f->gFile) { - oldfile = XP_STRDUP(f->gFile); - if (!oldfile) return; /* Out of memory... */ - } - f->gBookmarks = NULL; - f->gBookmarksModified = FALSE; /* Don't save now. */ - - /* save real stat 'cause it's about to get busted */ - XP_MEMCPY(&savedStat, &(f->laststat), sizeof(savedStat)); - - BM_ReadBookmarksFromDisk(context, newFile, NULL); - - /* restore real stat */ - XP_MEMCPY(&(f->laststat), &savedStat, sizeof(savedStat)); - - newroot = f->gBookmarks; - if (newroot && oldroot) { - /* Make the new stuff be the first folder of the old stuff. */ - f->gBookmarks = oldroot; - if (context->type == MWContextAddressBook) { - XP_ASSERT(BM_ISHEADER(newroot)); - if (BM_ISHEADER(newroot)) { - for (entry = newroot->d.header.children; - entry; - entry = next) { - next = entry->next; - entry->next = NULL; - bm_AddChildToHeaderSorted(context, oldroot, entry); - } - } - } else { - BM_PrependChildToHeader(context, oldroot, newroot); - } - f->menuheader = oldmenuheader; - f->addheader = oldaddheader; - } else { - f->gBookmarks = oldroot ? oldroot : newroot; - } - FREEIF(f->gFile); - f->gFile = oldfile; - oldfile = NULL; - bm_SetModified(context, TRUE); - bm_refresh(context, 1, BM_LAST_CELL); - XP_FREE(newFile); - } - bm_end_batch(context); -} - - -static void -bm_save_as_file(MWContext* context, char* saveName, void* closure) -{ - if (saveName) { - BM_SaveBookmarks(context, saveName); - XP_FREE(saveName); - } -} - - -static int -bm_comparenames(const void* e1, const void* e2) -{ -#ifdef INTL_SORT - return XP_StrColl((*((BM_Entry**)e1))->name, (*((BM_Entry**)e2))->name); -#else - return XP_STRCMP((*((BM_Entry**)e1))->name, (*((BM_Entry**)e2))->name); -#endif -} -static int -bm_comparenames_Asc(const void* e1, const void* e2) -{ -#ifdef INTL_SORT - return XP_StrColl((*((BM_Entry**)e2))->name, (*((BM_Entry**)e1))->name); -#else - return XP_STRCMP((*((BM_Entry**)e2))->name, (*((BM_Entry**)e1))->name); -#endif -} - -static int bm_compare_address( const void *elem1, const void *elem2 ) -{ - BM_Entry *p1 = *(BM_Entry **)elem1; - BM_Entry *p2 = *(BM_Entry **)elem2; - - if( !(p1->type == BM_TYPE_URL || - p1->type == BM_TYPE_ADDRESS) ) - { - if( !(p2->type == BM_TYPE_URL || - p2->type == BM_TYPE_ADDRESS) ) - { - return 0; - } - return -1; - } - else if( !(p2->type == BM_TYPE_URL || - p2->type == BM_TYPE_ADDRESS) ) - { - return 1; - } - - /* Note we rely on d.url.address is at same mem address as d.address.address */ - - #ifdef INTL_SORT - return XP_StrColl( p1->d.url.address, p2->d.url.address ); - #else - return XP_STRCMP( p1->d.url.address, p2->d.url.address ); - #endif -} -static int bm_compare_address_Asc( const void *elem1, const void *elem2 ) -{ - BM_Entry *p2 = *(BM_Entry **)elem1; - BM_Entry *p1 = *(BM_Entry **)elem2; - - if( !(p1->type == BM_TYPE_URL || - p1->type == BM_TYPE_ADDRESS) ) - { - if( !(p2->type == BM_TYPE_URL || - p2->type == BM_TYPE_ADDRESS) ) - { - return 0; - } - return -1; - } - else if( !(p2->type == BM_TYPE_URL || - p2->type == BM_TYPE_ADDRESS) ) - { - return 1; - } - - /* Note we rely on d.url.address is at same mem address as d.address.address */ - - #ifdef INTL_SORT - return XP_StrColl( p1->d.url.address, p2->d.url.address ); - #else - return XP_STRCMP( p1->d.url.address, p2->d.url.address ); - #endif -} - -#ifdef SUNOS4 -/* difftime() doesn't seem to exist on SunOS anywhere. -mcafee */ -static double difftime(time_t time1, time_t time0) -{ - return (double) (time1 - time0); -} -#endif - -static int bm_compare_time (time_t time1, time_t time0) -{ - double diff = difftime( time1, time0 ); - - if (diff > 0.0) return 1; - if (diff < 0.0) return -1; - - return 0; -} - -static int bm_compare_addition_date( const void *elem1, const void *elem2 ) -{ - BM_Entry *p1 = *(BM_Entry **)elem1; - BM_Entry *p2 = *(BM_Entry **)elem2; - - return bm_compare_time( p2->addition_date, p1->addition_date ); -} -static int bm_compare_addition_date_Asc( const void *elem1, const void *elem2 ) -{ - BM_Entry *p2 = *(BM_Entry **)elem1; - BM_Entry *p1 = *(BM_Entry **)elem2; - - return bm_compare_time( p2->addition_date, p1->addition_date ); -} - -static int bm_compare_natural( const void *elem1, const void *elem2 ) -{ - BM_Entry *p2 = *(BM_Entry **)elem1; - BM_Entry *p1 = *(BM_Entry **)elem2; - - return (p2->iNaturalIndex >= p1->iNaturalIndex) ? 1 : -1; -} - -static int bm_compare_last_visit( const void *elem1, const void *elem2 ) -{ - BM_Entry *p1 = *(BM_Entry **)elem1; - BM_Entry *p2 = *(BM_Entry **)elem2; - if( p2->type != BM_TYPE_URL ) - { - if( p1->type != BM_TYPE_URL ) - { - return 0; - } - return -1; - } - else if( p1->type != BM_TYPE_URL ) - { - return 1; - } - - return bm_compare_time( p2->d.url.last_visit, p1->d.url.last_visit ); -} -static int bm_compare_last_visit_Asc( const void *elem1, const void *elem2 ) -{ - BM_Entry *p2 = *(BM_Entry **)elem1; - BM_Entry *p1 = *(BM_Entry **)elem2; - if( p2->type != BM_TYPE_URL ) - { - if( p1->type != BM_TYPE_URL ) - { - return 0; - } - return -1; - } - else if( p1->type != BM_TYPE_URL ) - { - return 1; - } - - return bm_compare_time( p2->d.url.last_visit, p1->d.url.last_visit ); -} - -static void -bm_SortSelected_1(MWContext* context, BM_Entry* header, BM_SortType enSortType ) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry** list = NULL; - int numlist; - BM_Entry* entry; - BM_Entry* previous = NULL; - int i; -#ifdef XP_WIN - int (__cdecl *pfSort)(const void *, const void *); -#else - int (*pfSort)(const void *, const void *); -#endif - - XP_ASSERT(BM_ISHEADER(header)); - - switch( enSortType ) - { - case BM_Sort_Name: - pfSort = bm_comparenames; - break; - case BM_Sort_Name_Asc: - pfSort = bm_comparenames_Asc; - break; - - case BM_Sort_Address: - pfSort = bm_compare_address; - break; - case BM_Sort_Address_Asc: - pfSort = bm_compare_address_Asc; - break; - - case BM_Sort_AddDate: - pfSort = bm_compare_addition_date; - break; - case BM_Sort_AddDate_Asc: - pfSort = bm_compare_addition_date_Asc; - break; - - case BM_Sort_LastVisit: - pfSort = bm_compare_last_visit; - break; - case BM_Sort_LastVisit_Asc: - pfSort = bm_compare_last_visit_Asc; - break; - - case BM_Sort_Natural: - default: - pfSort = bm_compare_natural; - break; - } - - if (header->d.header.childCount == 0) return; - if (BM_ISSELECTED(header) && f->gSelectionCount == 1) { - numlist = header->d.header.childCount; - list = (BM_Entry**) XP_ALLOC(numlist * sizeof(BM_Entry*)); - if (!list) return; - for (i = 0, entry = header->d.header.children; - i < numlist; - i++, entry = entry->next) { - list[i] = entry; - } - } else { - i = 0; - for (entry = header->d.header.children ; entry ; entry = entry->next) { - if (BM_ISSELECTED(entry)) { - if (list == NULL) { - list = (BM_Entry**) XP_ALLOC(header->d.header.childCount * - sizeof(BM_Entry*)); - if (list == NULL) return; - } - list[i++] = entry; - } else { - if (list == NULL) previous = entry; - } - } - numlist = i; - } - if (list) { - if (numlist > 1) { - for (i=0 ; iname == NULL) { - list[i]->name = XP_STRDUP(""); - if (list[i]->name == NULL) return; - } - BM_RemoveChildFromHeader(context, header, list[i]); - } - XP_QSORT(list, numlist, sizeof(BM_Entry*), pfSort); - for (i=0 ; id.header.children ; entry ; entry = entry->next) { - if (BM_ISHEADER(entry)) bm_SortSelected_1(context, entry, enSortType ); - } -} - -static void -bm_SortSilent_1(MWContext* context, BM_Entry* header, BM_SortType enSortType ) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry** list = NULL; - int numlist; - BM_Entry* entry; - BM_Entry* previous = NULL; - int i; - XP_Bool bSelected = FALSE; -#ifdef XP_WIN - int (__cdecl *pfSort)(const void *, const void *); -#else - int (*pfSort)(const void *, const void *); -#endif - - XP_ASSERT(BM_ISHEADER(header)); - - switch( enSortType ) - { - case BM_Sort_Name: - pfSort = bm_comparenames; - break; - case BM_Sort_Name_Asc: - pfSort = bm_comparenames_Asc; - break; - - case BM_Sort_Address: - pfSort = bm_compare_address; - break; - case BM_Sort_Address_Asc: - pfSort = bm_compare_address_Asc; - break; - - case BM_Sort_AddDate: - pfSort = bm_compare_addition_date; - break; - case BM_Sort_AddDate_Asc: - pfSort = bm_compare_addition_date_Asc; - break; - - case BM_Sort_LastVisit: - pfSort = bm_compare_last_visit; - break; - case BM_Sort_LastVisit_Asc: - pfSort = bm_compare_last_visit_Asc; - break; - - case BM_Sort_Natural: - default: - pfSort = bm_compare_natural; - break; - } - - if (header->d.header.childCount == 0) return; - numlist = header->d.header.childCount; - list = (BM_Entry**) XP_ALLOC(numlist * sizeof(BM_Entry*)); - if (!list) return; - for (i = 0, entry = header->d.header.children; - i < numlist; - i++, entry = entry->next) { - list[i] = entry; - } - if (numlist > 1) { - for (i=0 ; iname == NULL) { - list[i]->name = XP_STRDUP(""); - if (list[i]->name == NULL) return; - } - if (BM_ISSELECTED(list[i])) { - BM_CLEARFLAG(list[i], BM_ATTR_SELECTED); - bSelected = TRUE; - } - BM_RemoveChildFromHeader(context, header, list[i]); - if (bSelected) { - BM_SETFLAG(list[i], BM_ATTR_SELECTED); - bSelected = FALSE; - } - } - XP_QSORT(list, numlist, sizeof(BM_Entry*), pfSort); - for (i=0 ; id.header.children ; entry ; entry = entry->next) { - if (BM_ISHEADER(entry)) bm_SortSilent_1(context, entry, enSortType ); - } -} - -/* -// Normalize bookmarks based on the current sort. Note the current sort -// should be the natural sort order (aka BM_Sort_Natural) as no other -// sort order has a mapping to the natural index. -*/ -static void -bm_Normalize(MWContext* context, BM_Entry* at) -{ - BM_Entry* nextChild; - BM_Entry* children; - - int32 iNaturalIndex = 0; - - while (at) { - nextChild = at->next; - if (BM_ISHEADER(at)) { - children = at->d.header.children; - } else { - children = NULL; - } - - at->iNaturalIndex = iNaturalIndex++; - - if (children) { - bm_Normalize(context, children); - } - - at = nextChild; - } -} - -static void -bm_SortSelected(MWContext* context, BM_SortType enSortType ) -{ - BM_Frame* f = GETFRAME(context); - if (f->gSelectionCount < 0) bm_SyncSelection(context); - if (f->enSortType == BM_Sort_Natural) bm_Normalize(context, BM_GetRoot(context)); - f->enSortType = enSortType; - f->bSorting = TRUE; - bm_SortSelected_1(context, BM_GetRoot(context), enSortType); - f->bSorting = FALSE; - bm_refresh(context, 1, BM_LAST_CELL); -} - -static void -bm_SortSilent(MWContext* context, BM_SortType enSortType ) -{ - BM_Frame* f = GETFRAME(context); - if (f->gSelectionCount < 0) bm_SyncSelection(context); - if (f->enSortType == BM_Sort_Natural) bm_Normalize(context, BM_GetRoot(context)); - f->enSortType = enSortType; - f->bSorting = TRUE; - bm_SortSilent_1(context, BM_GetRoot(context), enSortType); - f->bSorting = FALSE; -} - -static void bm_append_address_string(MWContext* context, BM_Entry* entry, - void* closure); - -static void -bm_append_fulladdress_string(MWContext* context, BM_Entry* entry, - void* closure) -{ - if (BM_ISALIAS(entry)) entry = entry->d.alias.original; - if (entry->flags & BM_ATTR_MARKED) return; - if (BM_ISHEADER(entry)) { - BM_SETFLAG(entry, BM_ATTR_MARKED); - for (entry = entry->d.header.children ; entry ; entry = entry->next) { - bm_append_fulladdress_string(context, entry, closure); - } - } else if (BM_ISADDRESS(entry)) { - bm_append_address_string(context, entry, closure); - XP_ASSERT(entry->flags & BM_ATTR_MARKED); - } -} - -static void -bm_append_address_string(MWContext* context, BM_Entry* entry, void* closure) -{ - if (BM_ISALIAS(entry)) entry = entry->d.alias.original; - if (entry->flags & BM_ATTR_MARKED) return; - if (BM_ISADDRESS(entry) || BM_ISHEADER(entry)) { - char* address = - BM_ISHEADER(entry) ? BM_GetNickName(entry) : BM_GetAddress(entry); - if (BM_ISHEADER(entry) && (address == NULL || *address == '\0')) { - /* No nickname for a header, so we don't have anything to write down - that we can remember later. Just write down all the members of - this list. */ - bm_append_fulladdress_string(context, entry, closure); - } else { -#ifdef MOZ_MAIL_NEWS - char** buf = (char**) closure; - char* full = MSG_MakeFullAddress(BM_GetName(entry), address); - if (full) { - if (*buf) NET_SACat(buf, ", "); - NET_SACat(buf, full); - XP_FREE(full); - } -#endif /* MOZ_MAIL_NEWS */ - } - } - BM_SETFLAG(entry, BM_ATTR_MARKED); -} - -char* -BM_GetFullAddress(MWContext* context, BM_Entry* entry) -{ - char* result = NULL; - bm_append_address_string(context, entry, &result); - return result; -} - -static void -bm_ComposeMessageToSelected(MWContext* context) -{ - char* buf = NULL; - char* tmp; - URL_Struct *url_struct; - bm_ClearMarkEverywhere(context); - BM_EachSelectedEntryDo(context, bm_append_address_string, &buf); - if (!buf) return; - tmp = NET_Escape(buf, URL_PATH); - XP_FREE(buf); - buf = tmp; - if (!buf) return; - tmp = XP_Cat("mailto:?to=", buf, (char*)/*Win16*/ NULL); - XP_FREE(buf); - buf = tmp; - if (!buf) return; - url_struct = NET_CreateURLStruct (buf, NET_NORMAL_RELOAD); - if (url_struct) { - url_struct->internal_url = TRUE; - FE_GetURL(context, url_struct); - } - XP_FREE(buf); -} - - -char* -BM_ExpandHeaderString(MWContext* context, const char* value, - XP_Bool expandfull) -{ - BM_Frame* f = GETFRAME(context); - char* name; - char* address; - char* curname; - char* curaddress; - char* pHashStr; - int num; - int i,j; - XP_Bool found = FALSE; - BM_Entry* entry; - char* result = NULL; - char* pTempStr = NULL; - int tempBufLen = 0; - CHKCONTEXT(context); -#ifdef MOZ_MAIL_NEWS - num = MSG_ParseRFC822Addresses(value, &name, &address); -#else - num = 0; -#endif /* MOZ_MAIL_NEWS */ - curname = name; - curaddress = address; - bm_ClearMarkEverywhere(context); - for (i=0 ; i tempBufLen)) { - FREEIF(pTempStr); - pTempStr = XP_STRDUP(curaddress); - tempBufLen = curlen; - } else { - /* just copy the string into the existing buffer */ - XP_STRCPY(pTempStr, curaddress); - } - if (pTempStr) { - /* now the buffer is loaded with the string, change the string to lowercase */ - for (j = 0; j < curlen; j++) { - if (isupper(pTempStr[j])) { - pTempStr[j] = (char)tolower(pTempStr[j]); - } - } - pHashStr = pTempStr; /* use the temp str for the hash function */ - } else { - pHashStr = curaddress; /* use the old string if low on memory */ - } - } - if (pHashStr && (entry = XP_Gethash(f->nicknameTable, pHashStr, NULL)) != NULL) { - found = TRUE; - if (expandfull) { - bm_append_fulladdress_string(context, entry, &result); - } else { - bm_append_address_string(context, entry, &result); - } - } else { - if (result) NET_SACat(&result, ", "); - if (*curname) { - NET_SACat(&result, curname); - NET_SACat(&result, " <"); - } - NET_SACat(&result, curaddress); - if (*curname) { - NET_SACat(&result, ">"); - } - } - curname += XP_STRLEN(curname) + 1; - curaddress += XP_STRLEN(curaddress) + 1; - } - FREEIF(name); - FREEIF(address); - FREEIF(pTempStr); - if (!found) { - FREEIF(result); /* Note this sets also result to NULL. */ - } - return result; -} - - - - - - -void BM_ObeyCommand(MWContext* context, BM_CommandType command) -{ - BM_Frame* f = GETFRAME(context); - BM_Entry* firstSelected; - - CHKCONTEXTVOID(context); - - if (!BM_FindCommandStatus(context, command)) return; - - firstSelected = BM_FirstSelectedItem(context); - - bm_start_batch(context); - - switch (command) { - case BM_Cmd_Invalid: - break; - - case BM_Cmd_Open: - FE_PromptForFileName(context, XP_GetString(XP_BKMKS_OPEN_BKMKS_FILE), - 0, TRUE, FALSE, bm_open_file, NULL); - break; - - case BM_Cmd_ImportBookmarks: - FE_PromptForFileName(context, - XP_GetString(context->type == MWContextAddressBook ? - XP_BKMKS_IMPORT_ADDRBOOK : XP_BKMKS_IMPORT_BKMKS_FILE), - 0, TRUE, FALSE, bm_import_file, NULL); - break; - - case BM_Cmd_SaveAs: - FE_PromptForFileName(context, - XP_GetString(context->type == MWContextAddressBook ? - XP_BKMKS_SAVE_ADDRBOOK : XP_BKMKS_SAVE_BKMKS_FILE), - 0, FALSE, FALSE, bm_save_as_file, NULL); - break; - - case BM_Cmd_Close: - BM_SaveBookmarks(context, f->gFile); - /* ### Maybe need to do more? */ - break; - - case BM_Cmd_Undo: - UNDO_EndBatch(f->undo, NULL, NULL); - UNDO_DoUndo(f->undo); - UNDO_StartBatch(f->undo); - bm_refresh(context, 1, BM_LAST_CELL); - bm_SyncCount(context); - break; - - case BM_Cmd_Redo: - UNDO_EndBatch(f->undo, NULL, NULL); - UNDO_DoRedo(f->undo); - UNDO_StartBatch(f->undo); - bm_refresh(context, 1, BM_LAST_CELL); - bm_SyncCount(context); - break; - - case BM_Cmd_Cut: - bm_cut(context); - break; - - case BM_Cmd_Copy: - bm_copy(context); - break; - - case BM_Cmd_Paste: - bm_paste(context); - break; - - case BM_Cmd_Delete: - bm_delete(context); - break; - - case BM_Cmd_SelectAllBookmarks: - BM_SelectAll(context, TRUE); - break; - - case BM_Cmd_Find: - bm_CloseLastFind(context); - bm_BeginFindBookmark(context); - break; - - case BM_Cmd_FindAgain: - bm_CloseLastFind(context); - BM_DoFindBookmark(context, f->gFindInfo); - break; - - case BM_Cmd_BookmarkProps: - if (firstSelected) { - BMFE_OpenBookmarksWindow(context); - BMFE_EditItem(context, firstSelected); - } - break; - - case BM_Cmd_GotoBookmark: - if (context->type == MWContextAddressBook) { - bm_ComposeMessageToSelected(context); - } else if (firstSelected) { - BM_GotoBookmark(context, firstSelected); - } - break; - - case BM_Cmd_Sort_Name: - case BM_Cmd_Sort_Name_Asc: - case BM_Cmd_Sort_Address: - case BM_Cmd_Sort_Address_Asc: - case BM_Cmd_Sort_AddDate: - case BM_Cmd_Sort_AddDate_Asc: - case BM_Cmd_Sort_LastVisit: - case BM_Cmd_Sort_LastVisit_Asc: - case BM_Cmd_Sort_Natural: - bm_SortSelected( context, (BM_SortType)(command-BM_Cmd_Sort_Name) ); - break; - - case BM_Cmd_InsertBookmark: - bm_BeginEditNewUrl(context); - break; - - case BM_Cmd_InsertHeader: - bm_BeginEditNewHeader(context); - break; - - case BM_Cmd_InsertSeparator: - if (firstSelected) { - bm_InsertItemAfter(context, firstSelected, bm_NewSeparator(), TRUE); - bm_refresh(context, BM_GetIndex(context, firstSelected) + 1, - BM_LAST_CELL); - } - break; - - case BM_Cmd_MakeAlias: - BM_MakeAliases(context); - break; - - case BM_Cmd_SetAddHeader: - if (firstSelected) { - BM_SetAddHeader(context, firstSelected); - } - break; - - case BM_Cmd_SetMenuHeader: - if (firstSelected) { - BM_SetMenuHeader(context, firstSelected); - } - break; - - default: - XP_ASSERT(0); - - } - bm_end_batch(context); -} - - - -/* Make sure that the given entry is a real entry, and not a pointer that has - since become invalid. */ - -static XP_Bool -bm_validate_entry(MWContext* context, BM_Entry* entry, BM_Entry* search) -{ - for (; entry ; entry = entry->next) { - if (entry == search) return TRUE; - if (BM_ISHEADER(entry)) { - if (bm_validate_entry(context, entry->d.header.children, search)) { - return TRUE; - } - } - } - return FALSE; -} - - -static void -bm_urlcheck_finished(URL_Struct* url_struct, int status, MWContext* context) -{ - BM_Frame* f = GETFRAME(context); - time_t now; - char timestr[40]; - if (f) { - struct BM_WhatsChangedInfo* w = (struct BM_WhatsChangedInfo *)&(f->whatschanged); - BM_Entry* entry = (BM_Entry*) url_struct->fe_data; - if (bm_validate_entry(context, BM_GetRoot(context), entry)) { - const char* url = BM_GetAddress(entry); - int32 oldstate = BM_GetChangedState(entry); - BM_CLEARFLAG(entry, BM_ATTR_CHECKING); - if (status >= 0) { - if (url && XP_STRCMP(url_struct->address, url) == 0) { - w->numreached++; - entry->d.url.last_modified = url_struct->last_modified; - if (entry->d.url.last_modified > entry->d.url.last_visit) { - w->numchanged++; - } - } - } else { - entry->d.url.last_modified = 0; - } - if (BM_GetChangedState(entry) != oldstate) { - bm_entry_changed(context, entry); - bm_SetModified(context, TRUE); - } - - now = time ((time_t *) 0); - - if (w->numreached == 0) { - XP_STRCPY(timestr, "???"); - } else { - int32 estimate = (now - w->starttime) * (w->total - w->numreached) / - w->numreached; - if (estimate < 2 * 60) { - PR_snprintf(timestr, sizeof(timestr), XP_GetString(XP_BKMKS_SECONDS), - estimate); - } else if (estimate < 2 * 60 * 60) { - PR_snprintf(timestr, sizeof(timestr), XP_GetString(XP_BKMKS_MINUTES), - estimate / 60); - } else { - PR_snprintf(timestr, sizeof(timestr), XP_GetString(XP_BKMKS_HOURS_MINUTES), - estimate / 3600, (estimate / 60) % 60); - } - } - BMFE_UpdateWhatsChanged(context, url, w->numreached, w->total, - timestr); - } - - /* Check to see if we're all done. First check to see if we're in the - middle of a batch operation; if we are, then we must be still setting - things up and we got called here because we had an invalid bookmark - and netlib called the exit routine immediately. In that case, we - don't want to say we're all done; we're probably still sending - URLs to netlib. - - If we're not in the middle of a batch operation, then we're all done - if there are no more outstanding connections on our context. */ - if (f->batch_depth == 0 && - !NET_AreThereActiveConnectionsForWindow(context)) { - BMFE_FinishedWhatsChanged(context, w->total, w->numreached, - w->numchanged); - } - } -} - -#ifdef XP_WIN16 -/* code segment is full, switch to a new segment */ -#pragma code_seg("BKMKS2_TEXT","CODE") -#endif - - - -static void -bm_urlcheck_start(MWContext* context, BM_Entry* entry) -{ - BM_Frame* f = GETFRAME(context); - char* url; - URL_Struct* url_struct; - - XP_ASSERT(entry); - - if (BM_ISALIAS(entry)) { - entry = entry->d.alias.original; - } - if (!entry) return; - - if (entry->flags & BM_ATTR_CHECKING) return; - - url = BM_GetAddress(entry); - if (!url) return; - url_struct = NET_CreateURLStruct(url, NET_SUPER_RELOAD); - if (!url_struct) return; - BM_SETFLAG(entry, BM_ATTR_CHECKING); - url_struct->method = URL_HEAD_METHOD; - url_struct->fe_data = entry; - f->whatschanged.total++; - NET_GetURL(url_struct, FO_PRESENT, context, bm_urlcheck_finished); -} - - - - -static void -bm_start_whats_changed_1(MWContext* context, BM_Entry* entry, - XP_Bool do_only_selected) -{ - for ( ; entry ; entry = entry->next) { - if (BM_ISURL(entry) || BM_ISALIAS(entry)) { - if (!do_only_selected || BM_ISSELECTED(entry)) { - bm_urlcheck_start(context, entry); - } - } else if (BM_ISHEADER(entry)) { - /* Recur through the children. If we are selected and folded, then - make sure we do all of our descendents. */ - bm_start_whats_changed_1(context, entry->d.header.children, - (BM_ISSELECTED(entry) && BM_ISFOLDED(entry)) ? - FALSE : do_only_selected); - } - } -} - - -static void -bm_clear_check_attr(MWContext* context, BM_Entry* entry, void* closure) -{ - BM_CLEARFLAG(entry, BM_ATTR_CHECKING); -} - - -int -BM_StartWhatsChanged(MWContext* context, XP_Bool do_only_selected) -{ - BM_Frame* f = GETFRAME(context); - struct BM_WhatsChangedInfo* w; - XP_ASSERT(context && context->type == MWContextBookmarks && f); - if (!context || context->type != MWContextBookmarks || !f) return -1; - w = &(f->whatschanged); - BM_CancelWhatsChanged(context); - XP_MEMSET(w, 0, sizeof(*w)); - w->starttime = time ((time_t *) 0); - - BM_EachEntryDo(context, bm_clear_check_attr, NULL); - - bm_start_batch(context); - bm_start_whats_changed_1(context, BM_GetRoot(context), do_only_selected); - -#if 0 - minutes = f->whatschanged.total * 35 / 60; - /* Assumes a maximum timeout of 35 seconds per - connection. Need to not hard-code - this... #### */ - if (minutes < 60) { - /* Fix i18n ### */ - PR_snprintf(w->totaltime, sizeof(w->totaltime), "%ld minutes", minutes); - } else { - /* Fix i18n ### */ - PR_snprintf(w->totaltime, sizeof(w->totaltime), "%ld hours", - (minutes / 60) + 1); - } -#endif - - BMFE_UpdateWhatsChanged(context, NULL, w->numreached, w->total, - "???"); /* Fix i18n ### */ - bm_refresh(context, 1, BM_LAST_CELL); - bm_end_batch(context); - if (!NET_AreThereActiveConnectionsForWindow(context)) { - /* All done, already (probably because nothing was selected). */ - BMFE_FinishedWhatsChanged(context, w->total, w->numreached, - w->numchanged); - } - return 0; -} - - -int -BM_CancelWhatsChanged(MWContext* context) -{ - XP_InterruptContext(context); - return 0; -} - -void BM_ResetUndo(MWContext * context) -{ - BM_Frame * f = GETFRAME(context); - UNDO_DiscardAll( f->undo ); -} - diff --git a/mozilla/lib/libmisc/bkmutils.c b/mozilla/lib/libmisc/bkmutils.c deleted file mode 100644 index 1a722b25948..00000000000 --- a/mozilla/lib/libmisc/bkmutils.c +++ /dev/null @@ -1,888 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#include "xp_mcom.h" -#include "client.h" -#include "hotlist.h" - -static int32 hot_measure_Separator(HotlistStruct * item, int bLongFormat, int nIndent); - - -#define TEXT_INDENT 3 -#define SEPATATOR_COUNT 20 -/* - * Measure a boring URL hotlist entry and return the length in bytes - * - * Short format: - * " item->address\n" - * where there are nIndent number of spaces before the item - * - * Long format: - * int16 type - * item->name\n - * item->address\n - * int32 addition_date - * int32 last_visit_date - * item->description\0 - * - * The item->description field is *NOT* \n terminated since it might - * be a multi-line string and is therefore \0 terminated - */ -PRIVATE int32 -hot_measure_URL(HotlistStruct * item, int bLongFormat, int nIndent) -{ - - int32 iSpace = 0; - - if(!item) - return(0); - - if(bLongFormat) { - - /* type, addition_date, last_visit_date + 2 \n's + 1 \0 */ - iSpace += 2 + 4 + 4 + 2 + 1; - - if(item->name) - iSpace += XP_STRLEN(item->name); - if(item->description) - iSpace += XP_STRLEN(item->description); - - } else { - - /* space indentation and '\n' terminator */ - iSpace = 1 + nIndent; - - } - - /* the address appears in both formats */ - if(item->address) - iSpace += XP_STRLEN(item->address); - - return(iSpace); - -} - -/* - * Measure a header entry and all its children - * - * Short format: - * " item->name\n" - * " child1->address\n" - * " child2->address\n" - * where there are nIndent number of spaces before the item and - * TEXT_INDENT spaces between levels - * - * Long format: - * int16 type - * item->name\n - * int32 addition_date - * int32 number of children - * item->description\0 - * - * The item->description field is *NOT* \n terminated since it might - * be a multi-line string and is therefore \0 terminated. Note that - * the address field is *NOT* written for headers since its it meaningless - */ -PRIVATE int32 -hot_measure_Header(HotlistStruct * item, int bLongFormat, int nIndent) -{ - - XP_List * list; - int32 iSpace = 0; - - if(!item) - return(0); - - if(bLongFormat) { - - /* type, addition_date, last_visit_date + # children + 2 \n's + 1 \0 */ - iSpace += 2 + 4 + 4 + 2 + 1; - - if(item->description) - iSpace += XP_STRLEN(item->description); - - } else { - - /* space indentation and '\n' terminator */ - iSpace = 1 + nIndent; - - } - - /* the name appears in both formats */ - if(item->name) - iSpace += XP_STRLEN(item->name); - - - /* if no children just return */ - if(!item->children) - return(iSpace); - - /* measure the amount of space taken up by this item's children */ - for(list = item->children->next; list; list = list->next) { - HotlistStruct * child = (HotlistStruct *) list->object; - - if(!child) - continue; - - switch(child->type) { - case HOT_URLType: - iSpace += hot_measure_URL(child, bLongFormat, nIndent + TEXT_INDENT); - break; - case HOT_HeaderType: - iSpace += hot_measure_Header(child, bLongFormat, nIndent + TEXT_INDENT); - break; - case HOT_SeparatorType: - iSpace += hot_measure_Separator(child, bLongFormat, nIndent + TEXT_INDENT); - break; - default: - break; - } - - } - - return(iSpace); - -} - - -/* - * Measure a separator entry and return the length in bytes - * - * Short format: - * " ---------------------\n" - * where there are nIndent number of spaces before the item - * and 20 dashes - * - * Long format: - * int16 type - */ -PRIVATE int32 -hot_measure_Separator(HotlistStruct * item, int bLongFormat, int nIndent) -{ - - int32 iSpace = 0; - - if(!item) - return(0); - - if(bLongFormat) { - - /* type */ - iSpace = 2; - - } else { - - /* space indentation and '\n' terminator */ - iSpace = 1 + nIndent + 20; - - } - - return(iSpace); - -} - - -/* - * Write out a boring URL hotlist entry. See comment at the top of - * hot_measure_URL for the format used. Assume we start writing at - * the start of the buffer passed in. Return a pointer to where the - * buffer ends when we get done. - */ -PRIVATE char * -hot_write_URL(char * buffer, HotlistStruct * item, int bLongFormat, int nIndent) -{ - - int iLen; - int32 lVal; - int32 sVal; - - if(!item || !buffer) - return(buffer); - - if(bLongFormat) { - - /* copy the type */ - sVal = (int16) item->type; - iLen = 2; - XP_MEMCPY(buffer, &sVal, iLen); - buffer += iLen; - - /* copy the name */ - if(item->name) { - iLen = XP_STRLEN(item->name); - XP_MEMCPY(buffer, item->name, iLen); - buffer += iLen; - } - - /* put the \n terminator on */ - *buffer++ = '\n'; - - /* copy the address */ - if(item->address) { - iLen = XP_STRLEN(item->address); - XP_MEMCPY(buffer, item->address, iLen); - buffer += iLen; - } - - /* put the \n terminator on */ - *buffer++ = '\n'; - - /* addition date */ - lVal = (int32) item->addition_date; - iLen = 4; - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* last visit date */ - lVal = (int32) item->last_visit; - iLen = 4; - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* copy the description */ - if(item->description) { - iLen = XP_STRLEN(item->description); - XP_MEMCPY(buffer, item->description, iLen); - buffer += iLen; - } - - /* put the \n terminator on */ - *buffer++ = '\0'; - - } else { - - XP_MEMSET(buffer, ' ', nIndent); - buffer += nIndent; - - if(item->address) { - XP_STRCPY(buffer, item->address); - buffer += XP_STRLEN(item->address); - } - - *buffer++ = '\n'; - - } - - return(buffer); - -} - -/* - * Write out a separator entry. See comment at the top of - * hot_measure_Separator for the format used. Assume we start writing at - * the start of the buffer passed in. Return a pointer to where the - * buffer ends when we get done. - */ -PRIVATE char * -hot_write_Separator(char * buffer, HotlistStruct * item, int bLongFormat, int nIndent) -{ - - int iLen; -#if 0 - int32 lVal; -#endif - int32 sVal; - - if(!item || !buffer) - return(buffer); - - if(bLongFormat) { - - /* copy the type */ - sVal = (int16) item->type; - iLen = 2; - XP_MEMCPY(buffer, &sVal, iLen); - buffer += iLen; - - } else { - - XP_MEMSET(buffer, ' ', nIndent); - buffer += nIndent; - - XP_MEMSET(buffer, '-', SEPATATOR_COUNT); - buffer += SEPATATOR_COUNT; - - *buffer++ = '\n'; - - } - - return(buffer); - -} - - -/* - * Write out a hotlist header entry. See comment at the top of - * hot_measure_Header for the format used. Assume we start writing at - * the start of the buffer passed in. Return a pointer to where the - * buffer ends when we get done. - */ -PRIVATE char * -hot_write_Header(char * buffer, HotlistStruct * item, int bLongFormat, int nIndent) -{ - - XP_List * list; - int iLen; - int32 lVal; - int32 sVal; - - if(!item || !buffer) - return(buffer); - - if(bLongFormat) { - - /* copy the type */ - sVal = (int16) item->type; - iLen = 2; - XP_MEMCPY(buffer, &sVal, iLen); - buffer += iLen; - - /* copy the name */ - if(item->name) { - iLen = XP_STRLEN(item->name); - XP_MEMCPY(buffer, item->name, iLen); - buffer += iLen; - } - - /* put the \n terminator on */ - *buffer++ = '\n'; - - /* addition date */ - lVal = (int32) item->addition_date; - iLen = 4; - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* number of children */ - lVal = XP_ListCount(item->children); - iLen = 4; - XP_MEMCPY(buffer, &lVal, iLen); - buffer += iLen; - - /* copy the description */ - if(item->description) { - iLen = XP_STRLEN(item->description); - XP_MEMCPY(buffer, item->description, iLen); - buffer += iLen; - } - - /* put the \n terminator on */ - *buffer++ = '\0'; - - } else { - - XP_MEMSET(buffer, ' ', nIndent); - buffer += nIndent; - - if(item->name) { - XP_STRCPY(buffer, item->name); - buffer += XP_STRLEN(item->name); - } - - *buffer++ = '\n'; - - } - - /* if no children just get out now */ - if(!item->children) - return(buffer); - - /* write out the children */ - for(list = item->children->next; list; list = list->next) { - HotlistStruct * child = (HotlistStruct *) list->object; - - if(!child) - continue; - - switch(child->type) { - case HOT_URLType: - buffer = hot_write_URL(buffer, child, bLongFormat, nIndent + TEXT_INDENT); - break; - case HOT_HeaderType: - buffer = hot_write_Header(buffer, child, bLongFormat, nIndent + TEXT_INDENT); - break; - case HOT_SeparatorType: - buffer = hot_write_Separator(buffer, child, bLongFormat, nIndent + TEXT_INDENT); - break; - default: - break; - } - - } - - return(buffer); - -} - - -/* - * Take a URL packed in a block the way hot_write_URL packs it. - * Return the new item if we created one - */ -PRIVATE HotlistStruct * -hot_read_URL(char * buffer, HotlistStruct * pListParent, HotlistStruct * item, int bLongFormat, int32 * lBytesEaten) -{ - - HotlistStruct * new_item = NULL; - - if(!buffer) - return(NULL); - - if(bLongFormat) { - - int32 addition, visit; - - /* get the name */ - char * name = buffer; - char * address = strchr(name, '\n'); - char * description = NULL; - char * ptr; - if(!address) - return(NULL); - - *address++ = '\0'; - - /* get the address */ - ptr = strchr(address, '\n'); - if(!ptr) - return(NULL); - - *ptr++ = '\0'; - - /* addition date */ - XP_MEMCPY(&addition, ptr, 4); - ptr += 4; - - /* visiting date */ - XP_MEMCPY(&visit, ptr, 4); - ptr += 4; - - /* get the description (it should be NULL terminated) */ - description = ptr; - - /* we should really strip leading whitespace */ - new_item = HOT_CreateEntry(HOT_URLType, name, address, 0, visit); - new_item->addition_date = addition; - new_item->description = XP_STRDUP(description); - *lBytesEaten = XP_STRLEN(description) + (description - buffer) + 1; - - } else { - - char * end = strchr(buffer, '\n'); - - /* if there was a return NULL terminate the current string */ - if(end) - *end++ = '\0'; - - /* we should really strip leading whitespace */ - new_item = HOT_CreateEntry(HOT_URLType, buffer, buffer, 0, 0); - new_item->addition_date = time ((time_t *) NULL); - *lBytesEaten = XP_STRLEN(buffer) + 1; - - } - - if(item) - HOT_InsertItemAfter(item, new_item); - else - HOT_InsertItemInHeaderOrAfterItem(pListParent, new_item); - - return(new_item); - -} - - -/* - * Take a separator and insert it - */ -PRIVATE HotlistStruct * -hot_read_Separator(char * buffer, HotlistStruct * pListParent, HotlistStruct * item, int bLongFormat, int32 * lBytesEaten) -{ -#if 0 - int32 kids = 0; - int16 sVal; -#endif - HotlistStruct * new_item = NULL; - - if(!buffer) - return(NULL); - - /* can only read long format headers */ - if(bLongFormat) { - - new_item = HOT_CreateEntry(HOT_SeparatorType, NULL, NULL, 0, 0); - *lBytesEaten = 0; - - if(item) - HOT_InsertItemAfter(item, new_item); - else - HOT_InsertItemInHeaderOrAfterItem(pListParent, new_item); - - return(new_item); - - } - - return(NULL); - -} - - - -/* - * Take a header and children packed in a block the way hot_write_Header - * packs it. Return the new header item if we created one - */ -PRIVATE HotlistStruct * -hot_read_Header(char * buffer, HotlistStruct * pListParent, HotlistStruct * item, int bLongFormat, int32 * lBytesEaten) -{ - - int32 kids = 0; - int16 sVal; - HotlistStruct * new_item = NULL; - - if(!buffer) - return(NULL); - - /* can only read long format headers */ - if(bLongFormat) { - - int32 addition; - - /* get the name */ - char * name = buffer; - char * ptr = strchr(name, '\n'); - char * description = NULL; - if(!ptr) - return(NULL); - - /* skip over the \n but change it to a \0 so strcpy() will work */ - *ptr++ = '\0'; - - /* addition date */ - XP_MEMCPY(&addition, ptr, 4); - ptr += 4; - - /* number of children to read */ - XP_MEMCPY(&kids, ptr, 4); - ptr += 4; - - /* get the description (it should be NULL terminated) */ - description = ptr; - - /* we should really strip leading whitespace */ - new_item = HOT_CreateEntry(HOT_HeaderType, name, NULL, 0, 0); - new_item->addition_date = addition; - new_item->description = XP_STRDUP(description); - *lBytesEaten = XP_STRLEN(description) + (description - buffer) + 1; - - /* handle all of the kids now */ - if(kids) { - - int i; - HotlistStruct * kid = NULL; - - new_item->children = XP_ListNew(); - buffer += *lBytesEaten; - - for(i = 0; i < kids; i++) { - - int32 lEat; - - /* determine the type of the next entry */ - sVal = 0; - XP_MEMCPY(&sVal, buffer, 2); - buffer += 2; - *lBytesEaten += 2; - - switch(sVal) { - case HOT_URLType: - kid = hot_read_URL(buffer, new_item, kid, bLongFormat, &lEat); - *lBytesEaten += lEat; - buffer += lEat; - break; - case HOT_HeaderType: - kid = hot_read_Header(buffer, new_item, kid, bLongFormat, &lEat); - *lBytesEaten += lEat; - buffer += lEat; - break; - case HOT_SeparatorType: - kid = hot_read_Separator(buffer, new_item, kid, bLongFormat, &lEat); - *lBytesEaten += lEat; - buffer += lEat; - break; - default: - /* bogus type. Who knows whats going on. Just quit and get out */ - break; - } - - } - - } else { - - /* no kids */ - new_item->children = NULL; - - } - - } - - if(item) - HOT_InsertItemAfter(item, new_item); - else - HOT_InsertItemInHeaderOrAfterItem(pListParent, new_item); - - return(new_item); - -} - - - -/* - * Allocate and return a string that contains the text representation of - * a list of hotlist entries (including headers and their contents). - * The caller is responsible for freeing the string - */ -PUBLIC char * -HOT_ConvertSelectionsToBlock(HotlistStruct ** list, int iCount, int bLongFormat, int32 * lTotalLen) -{ - - int i, j; - int bSkip; - int16 marker; - int32 iSpace = 0; - HotlistStruct * item; - HotlistStruct * pParent; - char * pString; - char * pOriginal; - - for(i = 0; i < iCount; i++) { - - /* don't skip yet */ - bSkip = FALSE; - - /* make sure we have a valid item */ - item = list[i]; - if(!item) - continue; - - /* - * if our parent is in the list don't add ourselves, we will have - * been added when our parent got added. Ugh. This is going to be - * n^2 over the number of selected items - */ - for(pParent = item->parent; pParent && !bSkip; pParent = pParent->parent) { - for(j = 0; (j < iCount) && (!bSkip) ; j++) - if(list[j] == pParent) - bSkip = TRUE; - } - - if(bSkip) - continue; - - /* decide how much space we need */ - switch(item->type) { - case HOT_URLType: - iSpace += hot_measure_URL(item, bLongFormat, 0); - break; - case HOT_HeaderType: - iSpace += hot_measure_Header(item, bLongFormat, 0); - break; - case HOT_SeparatorType: - iSpace += hot_measure_Separator(item, bLongFormat, 0); - break; - default: - break; - } - - } - - /* leave room for end of list marker */ - if(bLongFormat) - iSpace += 2; - - /* leave room for the termination character */ - iSpace++; - -#ifdef XP_WIN16 - if(iSpace > 32000) - return(NULL); -#endif - - /* allocate the string */ - pOriginal = pString = (char *) XP_ALLOC(iSpace * sizeof(char)); - if(!pString) - return(NULL); - - /* Make a big string */ - for(i = 0; i < iCount; i++) { - - bSkip = FALSE; - - /* make sure we have a valid item */ - item = list[i]; - if(!item) - continue; - - /* - * if our parent is in the list don't add ourselves, we will have - * been added when our parent got added. Ugh. This is going to be - * n^2 over the number of selected items - */ - for(pParent = item->parent; pParent && !bSkip; pParent = pParent->parent) { - for(j = 0; (j < iCount) && (!bSkip) ; j++) - if(list[j] == pParent) - bSkip = TRUE; - } - - if(bSkip) - continue; - - /* write out the item */ - switch(item->type) { - case HOT_URLType: - pString = hot_write_URL(pString, item, bLongFormat, 0); - break; - case HOT_HeaderType: - pString = hot_write_Header(pString, item, bLongFormat, 0); - break; - case HOT_SeparatorType: - pString = hot_write_Separator(pString, item, bLongFormat, 0); - break; - default: - break; - } - - } - - /* stick the end of list marker on so that when we are decoding this */ - /* block we know when we are done */ - if(bLongFormat) { - marker = 12345; - XP_MEMCPY(pString, &marker, 2); - pString +=2; - } - - /* end the string and return the total length to our caller */ - *pString++ = '\0'; - *lTotalLen = (pString - pOriginal); - return(pOriginal); - -} - - - -/* - * Take a block of memory formatted by HOT_ConvertSelectionsToBlock and insert - * the items it represents into the hotlist following 'item'. If item is - * NULL insert at the beginning of the hotlist. - */ -PUBLIC void -HOT_InsertBlockAt(char * pOriginalBlock, HotlistStruct * item, int bLongFormat, int32 lTotalLen) -{ - - int16 sVal; /* 16-bit scratch variable */ - int32 lBytesEaten = 0; /* total number of bytes eaten */ - int32 lEat; /* number of bytes eaten on this item */ - char * pCurrentPos; - char * pBlock; - HotlistStruct * pParent = HOT_GetHotlist(); - - if(!pOriginalBlock) - return; - - /* make a copy of the string we can write into */ - pCurrentPos = pBlock = (char *) XP_ALLOC(lTotalLen + 1); - if(!pBlock) - return; - - /* copy the data over and make sure we are NULL terminated to make life easier */ - XP_MEMCPY(pBlock, pOriginalBlock, lTotalLen); - pBlock[lTotalLen] = '\0'; - - /* - * if our very first element is a header then we really want to insert - * everything into the header and not after it --- I think. - */ - if(item && item->type == HOT_HeaderType) { - pParent = item; - item = NULL; - - /* - * gack! if we are inserting under a header make sure its set up - * to accept children - */ - if(!pParent->children) - pParent->children = XP_ListNew(); - } - - /* long format can have all kinds of different types of things in it */ - if(bLongFormat) { - - while(lBytesEaten < lTotalLen) { - - /* determine the type of the next entry */ - sVal = 0; - XP_MEMCPY(&sVal, pCurrentPos, 2); - pCurrentPos += 2; - lBytesEaten += 2; - - switch(sVal) { - case HOT_URLType: - item = hot_read_URL(pCurrentPos, pParent, item, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - break; - case HOT_HeaderType: - item = hot_read_Header(pCurrentPos, pParent, item, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - break; - case HOT_SeparatorType: - item = hot_read_Separator(pCurrentPos, pParent, item, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - break; - default: - /* bogus type. Who knows whats going on. Just quit and get out */ - return; - break; - } - - } - - } else { - - /* short format is just a list of URLs separated by \n's */ - while(lBytesEaten < lTotalLen) { - - item = hot_read_URL(pCurrentPos, pParent, item, bLongFormat, &lEat); - lBytesEaten += lEat; - pCurrentPos += lEat; - - /* if we just walked over a \0 we are done */ - if(pOriginalBlock[lBytesEaten - 1] == '\0') - lBytesEaten = lTotalLen; - - } - - } - - /* mark the bookmark list as changed and clean up */ - HOT_SetModified(); - XP_FREE(pBlock); - -} diff --git a/mozilla/lib/libmisc/glhist.c b/mozilla/lib/libmisc/glhist.c index 4d96a42f7a4..db36bc98851 100644 --- a/mozilla/lib/libmisc/glhist.c +++ b/mozilla/lib/libmisc/glhist.c @@ -27,9 +27,6 @@ #include #include "merrors.h" #include "xpgetstr.h" -#if !defined(XP_MAC) /* macOS doesn't need this, but other platforms may still */ - #include "bkmks.h" -#endif #include "prefapi.h" #include "xplocale.h" #include "libi18n.h" diff --git a/mozilla/lib/libmisc/hotlist.c b/mozilla/lib/libmisc/hotlist.c deleted file mode 100644 index 0f148ad45c6..00000000000 --- a/mozilla/lib/libmisc/hotlist.c +++ /dev/null @@ -1,1455 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#include "hotlist.h" -#include "net.h" -#include "xp_mcom.h" -#include "client.h" -#include "xpgetstr.h" - -extern int XP_HOTLIST_DEF_NAME; -extern int XP_HOTLIST_AUTOGENERATED_FILE; - -#define DEF_NAME XP_GetString(XP_HOTLIST_DEF_NAME) - -/* - Private Prototypes -*/ - -#ifdef NOPE -PRIVATE HotlistStruct * -hot_FindItemsParent(HotlistStruct * parent_node, HotlistStruct * item); -#endif - -HotlistStruct * -hot_GetIndexOf(HotlistStruct *parent, int *index); - -/* the main parent node - */ -PRIVATE HotlistStruct * hot_list=0; -PRIVATE XP_Bool hot_list_modified=FALSE; - -/* return a pointer to the main hotlist list - * - * returns NULL if nothing has ever been - * added to the hotlist - */ -PUBLIC XP_List * -HOT_GetHotlistList(void) -{ - if (! hot_list) return 0; - return (hot_list->children); -} - -/* tell the hotlist code that the hotlist has been modified - * so that it gets saved the next time SaveHotlist is called - */ -PUBLIC void -HOT_SetModified(void) -{ - hot_list_modified=TRUE; -} - -PRIVATE HotlistStruct * -hot_FindItemStub(HotlistStruct *parent, char * url_address) -{ - XP_List * list_ptr; - HotlistStruct * object; - - if(parent == NULL) /* Eric made me do it */ - return(0); - - list_ptr = parent->children; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - - if(object->address && !XP_STRCMP(object->address, url_address)) - { - return(object); - } - - if(object->type == HOT_HeaderType) - { - HotlistStruct * rv; - rv = hot_FindItemStub(object, url_address); - - if(rv) - return(rv); - } - } - - return(0); -} - -/* checks the hotlist for a url and updates the last accessed - * time - */ -PUBLIC void -HOT_UpdateHotlistTime(URL_Struct *URL_s, time_t cur_time) -{ - HotlistStruct * hs = hot_FindItemStub(hot_list, URL_s->address); - - if(hs) - { - TRACEMSG(("Updating hotlist item access time: %s", hs->address)); - hs->last_visit = cur_time; - hot_list_modified = TRUE; - } -} - -/* create a hotlist entry struct and fill it in with - * the passed in data - * - * returns NULL on out of memory error. - */ -PUBLIC HotlistStruct * -HOT_CreateEntry(HOT_Type type, - const char *name, - const char *address, - const char *content_type, - time_t last_visit) -{ - HotlistStruct * new_entry = XP_NEW(HotlistStruct); - - if(!new_entry) - return(NULL); - - memset(new_entry, 0, sizeof(HotlistStruct)); - - new_entry->type = type; - - if(type == HOT_HeaderType) - new_entry->children = XP_ListNew(); - else - StrAllocCopy(new_entry->address, address); /* headers can't have addresses */ - - StrAllocCopy(new_entry->name, name); - StrAllocCopy(new_entry->content_type, content_type); - new_entry->last_visit = last_visit; - new_entry->addition_date = time(NULL); - new_entry->parent = NULL; - new_entry->lParent = NULL; - - return(new_entry); -} - -/* free's a hotlist entry - */ -PUBLIC void -HOT_FreeEntry(HotlistStruct * entry) -{ - if(entry) - { - if(entry->type == HOT_HeaderType) - { - HotlistStruct * subItem; - - while((subItem = (HotlistStruct *) XP_ListRemoveTopObject(entry->children))!=0) - { - HOT_FreeEntry(subItem); - } - - XP_ListDestroy(entry->children); - } - - if(entry->name) - XP_FREE(entry->name); - if(entry->address) - XP_FREE(entry->address); - if(entry->content_type) - XP_FREE(entry->content_type); - XP_FREE(entry); - } -} - -/* changes a entry to a header type from a non header type - * and vice versa. If the object was a header and - * has children, the children will be blown away. (very bad) - */ -PUBLIC void -HOT_ChangeEntryType(HotlistStruct * entry, HOT_Type type) -{ - if(entry->type == type) - return; - - entry->type = type; - if(entry->type == HOT_HeaderType) - { - entry->children = XP_ListNew(); - } - else - { - XP_ListDestroy(entry->children); - entry->children = NULL; - } - - hot_list_modified = TRUE; -} - - -/* create a completely new copy of the entry passed in - */ -PUBLIC HotlistStruct * -HOT_CopyEntry(HotlistStruct * entry) -{ - if(!entry) - return(NULL); - - return(HOT_CreateEntry(entry->type, - entry->name, - entry->address, - entry->content_type, - entry->last_visit)); -} - -/* Fold or unfold a hotlist header - * - * set the Boolean to True to fold the list and - * False to unfold - */ -PUBLIC void -HOT_FoldHeader(HotlistStruct * item, Bool fold) -{ - hot_list_modified = TRUE; - - if(item) - item->is_folded = fold; -} - -#ifdef NOPE -/* recursive routine to find a HotlistStruct parent structure containing - * the list containing the specified hotlist item - */ -PRIVATE HotlistStruct * -hot_FindItemsParent(HotlistStruct * parent_node, HotlistStruct * item) -{ - XP_List *cur_list = parent_node->children->next; - - if(!cur_list) - return(NULL); - - while(cur_list) - { - HotlistStruct *rv = NULL; - HotlistStruct *obj = (HotlistStruct *)cur_list->object; - - if(obj == item) - { - return(parent_node); - } - else if(obj->type == HOT_HeaderType) - { - rv = hot_FindItemsParent(obj, item); - if(rv) - return(rv); - } - cur_list = cur_list->next; - } - - return(NULL); /* not found */ -} - - -#endif - -/* insert an item before another item in the hotlist - * - * if the insert_before item is NULL or not found the item - * will be inserted at the begining of the list - */ -PUBLIC void -HOT_InsertItemBefore(HotlistStruct * insert_before, HotlistStruct * insertee) -{ - HotlistStruct * hls=0; - - if(!insertee) - return; - - hot_list_modified = TRUE; - - if(!hot_list) - { - hot_list = HOT_CreateEntry (HOT_HeaderType, XP_GetString(XP_HOTLIST_DEF_NAME), NULL, NULL, 0); - if(!hot_list) - return; - hot_list->children = XP_ListNew(); - if (!hot_list->children) - { - HOT_FreeEntry(hot_list); - hot_list = NULL; - return; - } - } - - /* find the list that contains the insert_before object - */ - if(insert_before) { - if(insert_before->parent) { - hls = insert_before->parent; - XP_ListInsertObject(hls->children, insert_before, insertee); - insertee->parent = hls; - insertee->lParent = XP_ListFindObject(hls->children, insertee); - } else { - XP_ListInsertObject(hot_list->children, insert_before, insertee); - insertee->parent = NULL; - insertee->lParent = XP_ListFindObject(hot_list->children, insertee); - } - } else { - XP_ListAddObjectToEnd(hot_list->children, insertee); - insertee->parent = NULL; - insertee->lParent = XP_ListFindObject(hot_list->children, insertee); - } - - return; -} - -/* insert an item after another item in the hotlist - * - * if the insert_after item is NULL or not found the item - * will be inserted at the end of the list - */ -PUBLIC void -HOT_InsertItemAfter(HotlistStruct * insert_after, HotlistStruct * insertee) -{ - HotlistStruct * hls=0; - - if(!insertee) - return; - - hot_list_modified = TRUE; - - if(!hot_list) - { - hot_list = HOT_CreateEntry(HOT_HeaderType, DEF_NAME, NULL, NULL, 0); - if(!hot_list) - return; - hot_list->children = XP_ListNew(); - } - - /* find the list that contains the insert_after object - */ - if(insert_after) { - if(insert_after->parent) { - hls = insert_after->parent; - XP_ListInsertObjectAfter(hls->children, insert_after, insertee); - insertee->parent = hls; - insertee->lParent = XP_ListFindObject(hls->children, insertee); - } else { - XP_ListInsertObjectAfter(hot_list->children, insert_after, insertee); - insertee->parent = NULL; - insertee->lParent = XP_ListFindObject(hot_list->children, insertee); - } - } else { - XP_ListAddObjectToEnd(hot_list->children, insertee); - insertee->parent = NULL; - insertee->lParent = XP_ListFindObject(hot_list->children, insertee); - } - - return; -} - -/* insert an item in a header if "insert_after" is a - * Header type, or after the item if "insert after" is - * not a header type. - * - * if the insert_after item is NULL or not found the item - * will be inserted at the end of the hotlist - */ -PUBLIC void -HOT_InsertItemInHeaderOrAfterItem(HotlistStruct * insert_after, - HotlistStruct * insertee) -{ - if(!insertee) - return; - - if(insert_after && insert_after->type == HOT_HeaderType) - { - XP_ListAddObject(insert_after->children, insertee); - if(insert_after != hot_list) - insertee->parent = insert_after; - else - insertee->parent = NULL; - insertee->lParent = XP_ListFindObject(insert_after->children, insertee); - return; - } - - /* else */ - HOT_InsertItemAfter(insert_after, insertee); -} - - -/* remove an item from the hotlist and free's it - * - * returns TRUE on success, FALSE if not found - */ -PUBLIC Bool -HOT_RemoveItem(HotlistStruct * old_item) -{ - HotlistStruct * hls = old_item->parent; - if(!hls) - hls = hot_list; - - hot_list_modified = TRUE; - - if(hls) - { - XP_ListRemoveObject(hls->children, old_item); - HOT_FreeEntry(old_item); - return(TRUE); - } - - /* else */ - return(FALSE); -} - -/* remove an item from the hotlist and doesn't free it - * - * returns TRUE on success, FALSE if not found - */ -PUBLIC Bool -HOT_RemoveItemFromList(HotlistStruct * old_item) -{ - HotlistStruct * hls = old_item->parent; - if(!hls) - hls = hot_list; - - hot_list_modified = TRUE; - - if(hls) - { - XP_ListRemoveObject(hls->children, old_item); - return(TRUE); - } - - /* else */ - return(FALSE); -} - -PRIVATE int -hot_GetIndexNum(HotlistStruct *parent, HotlistStruct * item, int *cur_count) -{ - XP_List * list_ptr = parent->children; - HotlistStruct * object; - int rv=0; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - - if(object == item) - return(*cur_count); - - *(cur_count) += 1; - - if(object->type == HOT_HeaderType && !object->is_folded) - { - rv = hot_GetIndexNum(object, item, cur_count); - - if(rv) - return(rv); - } - } - - return(0); -} - -/* returns an integer index of the item in the list - */ -PUBLIC int -HOT_GetIndex(HotlistStruct * item) -{ - int count=1; - - if(hot_list) - return(hot_GetIndexNum(hot_list, item, &count)); - else - return(0); -} - -PRIVATE int -hot_GetUnfoldedIndexNum(HotlistStruct *parent, HotlistStruct * item, int *cur_count) -{ - XP_List * list_ptr = parent->children; - HotlistStruct * object; - int rv=0; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - - if(object == item) - return(*cur_count); - - *(cur_count) += 1; - - if(object->type == HOT_HeaderType) - { - rv = hot_GetUnfoldedIndexNum(object, item, cur_count); - - if(rv) - return(rv); - } - } - - return(0); -} - -/* returns an integer index of the item in the list - * and does not pay attention to the is_folded value - */ -PUBLIC int -HOT_GetUnfoldedIndex(HotlistStruct * item) -{ - int count=1; - - if(hot_list) - return(hot_GetUnfoldedIndexNum(hot_list, item, &count)); - else - return(0); -} - -/* returns TRUE if the second argument is a direct - * descendent of the first argument. - * - * returns FALSE otherwise - */ -PUBLIC Bool -HOT_IsDescendent(HotlistStruct *parent, HotlistStruct *possible_child) -{ - int count = 1; - - if(parent - && parent->type == HOT_HeaderType - && hot_GetUnfoldedIndexNum(parent, possible_child, &count)) - return(TRUE); - - return(FALSE); -} - -PRIVATE HotlistStruct * -hot_SearchHotlistStub(HotlistStruct *parent, - char * search_string, - HotlistStruct ** start_obj, - int *cur_count, - Bool *redisplay_all) -{ - XP_List * list_ptr = parent->children; - HotlistStruct * object; - HotlistStruct * rv; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - - if(object == *start_obj) - *start_obj = NULL; - else if(!*start_obj && - ((object->name && strcasestr(object->name, search_string)) || - (object->address && strcasestr(object->address, search_string)))) - return(object); - - *(cur_count) += 1; - - if(object->type == HOT_HeaderType) - { - rv = hot_SearchHotlistStub(object, - search_string, - start_obj, - cur_count, - redisplay_all); - if(rv) - { - if(object->is_folded) - { - *redisplay_all = TRUE; - object->is_folded = FALSE; - } - - return(rv); - } - } - } - - return(NULL); -} - -/* Performs regular expression match on hotlist name and address - * fields. Returns the found object, or NULL if not - * found. - * - * start_obj specifies the object to start searching - * on. The start_num object WILL NOT be searched but all those - * after it will be. - * To search the whole list give NULL as start_obj. - * - * If headers became unfolded because of the search then redisplay_all - * will be set to TRUE - */ -PUBLIC HotlistStruct * -HOT_SearchHotlist(char * search_string, HotlistStruct * start_obj, Bool * redisplay_all) -{ - int count=1; - - *redisplay_all = FALSE; - - if(hot_list) - return(hot_SearchHotlistStub(hot_list, - search_string, - &start_obj, - &count, - redisplay_all)); - else - return(NULL); -} - - -PRIVATE int -hot_GetObjDepth(HotlistStruct *parent, HotlistStruct * item, int cur_depth) -{ - XP_List * list_ptr = parent->children; - HotlistStruct * object; - int rv=0; - - cur_depth++; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - - if(object == item) - return(cur_depth); - - if(object->type == HOT_HeaderType) - { - rv = hot_GetObjDepth(object, item, cur_depth); - - if(rv) - return(rv); - } - } - - return(0); -} - -/* returns an integer depth of the item in the list starting at zero - */ -PUBLIC int -HOT_GetDepth(HotlistStruct * item) -{ - - if(hot_list) - return(hot_GetObjDepth(hot_list, item, -1)); - else - return(0); -} - - -PUBLIC HotlistStruct * -hot_GetIndexOf(HotlistStruct *parent, int *index) -{ - HotlistStruct * rv=0; - HotlistStruct * object; - XP_List * list_ptr = parent->children; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - *(index) -= 1; - - if(*index <= 0) - return(object); - - if(object->type == HOT_HeaderType && !object->is_folded) - { - rv = hot_GetIndexOf(object, index); - - if(rv) - return(rv); - } - } - - return(NULL); -} - -/* returns the object associated with the index returned by - * HOT_GetIndex() - */ -PUBLIC HotlistStruct * -HOT_IndexOf(int index) -{ - TRACEMSG(("HOT_IndexOf: Getting index: %d",index)); - - if(hot_list && index > 0) - return(hot_GetIndexOf(hot_list, &index)); - else - return(NULL); -} - -PUBLIC HotlistStruct * -hot_GetUnfoldedIndexOf(HotlistStruct *parent, int *index) -{ - HotlistStruct * rv=0; - HotlistStruct * object; - XP_List * list_ptr = parent->children; - - while((object = (HotlistStruct *)XP_ListNextObject(list_ptr))!=0) - { - *(index) -= 1; - - if(*index <= 0) - return(object); - - if(object->type == HOT_HeaderType) - { - rv = hot_GetUnfoldedIndexOf(object, index); - - if(rv) - return(rv); - } - } - - return(NULL); -} - -/* returns the object associated with the index returned by - * HOT_GetUnfoldedIndex() - */ -PUBLIC HotlistStruct * -HOT_UnfoldedIndexOf(int index) -{ - TRACEMSG(("HOT_IndexOf: Getting index: %d",index)); - - if(hot_list && index > 0) - return(hot_GetUnfoldedIndexOf(hot_list, &index)); - else - return(NULL); -} - - -PRIVATE HotlistStruct * -hot_FindLastItem(HotlistStruct * item) -{ - if(item->type == HOT_HeaderType) - { - HotlistStruct * rv = (HotlistStruct *)XP_ListGetEndObject(item->children); - if(rv) - return(hot_FindLastItem(rv)); - } - - return(item); -} - -/* move an item up in the list - */ -PUBLIC void -HOT_MoveObjectUp(HotlistStruct * item) -{ - HotlistStruct * hls = item->parent; - if(!hls) - hls = hot_list; - - hot_list_modified = TRUE; - - if(hls) - { - /* find the previous object in the list - */ - XP_List *prev=0; - XP_List *list_ptr = hls->children; - HotlistStruct * prev_item; - - while (list_ptr->next) - { - prev = list_ptr; - list_ptr = list_ptr->next; - if (item == (HotlistStruct *)list_ptr->object) - { - prev_item = (HotlistStruct *)prev->object; - - if(prev_item) - { - /* remove the item from the list - */ - XP_ListRemoveObject(hls->children, item); - - if(prev_item->type != HOT_HeaderType || prev_item->is_folded) - { - HOT_InsertItemBefore(prev_item, item); - TRACEMSG(("Normal jump move")); - } - else - { - /* add to end of children list - */ - XP_ListAddObjectToEnd(prev_item->children, item); - item->lParent = XP_ListFindObject(prev_item->children, item); - item->parent = prev_item; - TRACEMSG(("Addition to list above")); - } - return; - } - else - { - /* oh nasty, now we have to move object to a higher list - */ - if(hls == hot_list) - return; /* cannot move it up, already at the top */ - - /* remove the item from the other list - */ - XP_ListRemoveObject(hls->children, item); - - HOT_InsertItemBefore(hls, item); - - return; - } - } - } - } -} - -/* returns True if the object can be moved Up - * False if the object cannot be moved Up or if - * it cannot be found in the list - */ -PUBLIC Bool -HOT_ObjectCanGoUp(HotlistStruct * item) -{ - /* this is sortof a hack. - * find the index of item. - * if greater than one then it can go up - */ - int item_count = HOT_GetIndex(item); - - if(item_count > 1) - return(TRUE); - - return(FALSE); - -} - - - - - -/* move an item down in the list - */ -PUBLIC void -HOT_MoveObjectDown(HotlistStruct * item) -{ - HotlistStruct * hls = item->parent; - if(!hls) - hls = hot_list; - - hot_list_modified = TRUE; - - if(hls) - { - /* find the object in the list - */ - XP_List *list_ptr = hls->children; - XP_List *prev; - XP_List *next_ptr; - HotlistStruct * next_item; - - while (list_ptr->next) - { - prev = list_ptr; - list_ptr = list_ptr->next; - if (item == (HotlistStruct *)list_ptr->object) - { - next_ptr = list_ptr->next; - - if(list_ptr->next) - { - next_item = (HotlistStruct *)next_ptr->object; - - if(next_item->type == HOT_HeaderType) - { - /* remove the item from list - */ - XP_ListRemoveObject(hls->children, item); - - if(next_item->is_folded) - { - /* add right after folded lists - */ - HOT_InsertItemAfter(next_item, item); -TRACEMSG(("Moving item after folded list")); - } - else - { - /* add to top of children list - */ - XP_ListAddObject(next_item->children, item); - item->lParent = XP_ListFindObject(next_item->children, item); - item->parent = next_item; -TRACEMSG(("Moving item into list")); - } - - return; - } - else - { - /* move it after the next one */ - /* remove the item from list - */ - XP_ListRemoveObject(hls->children, item); - - XP_ListInsertObjectAfter(hls->children, - next_ptr->object, - item); - item->lParent = XP_ListFindObject(hls->children, item); -TRACEMSG(("Moving item after normal item")); - return; - } - } - else - { - if(hls == hot_list) - return; /* cannot move it down, already at the bottom */ - - /* remove the item from list - */ - XP_ListRemoveObject(hls->children, item); -TRACEMSG(("Moving item down a hicharchy")); - - HOT_InsertItemAfter(hls, item); - return; - } - } - } - } -} - -/* returns True if the object can be moved down - * False if the object cannot be moved down or if - * it cannot be found in the list - */ -PUBLIC Bool -HOT_ObjectCanGoDown(HotlistStruct * item) -{ - /* this is sortof a hack. - * find the index of item. - * if found then try and find - * an object with an index one higher - * than item. If it exists then the - * object can move down :) - */ - int item_count = HOT_GetIndex(item); - - if(item_count) - { - item_count++; - - /* if there are other object below it we can obviously - * move down - */ - if(HOT_IndexOf(item_count)) - return(TRUE); - - /* if the object is at a depth other than the first - * then we can move down as well - */ - if(HOT_GetDepth(item) > 0) - return(TRUE); - } - - return(FALSE); -} - -#define HOTLIST_COOKIE "" - -#define READ_BUFFER_SIZE 2048 - -PRIVATE void -hot_ReadSaveList(XP_File fp, HotlistStruct * item, char *buffer, char * relative_url) -{ - char *ptr, *end, *url; - HotlistStruct * new_item=0; - Bool item_saved=FALSE; - char *buffer_ptr; - - /* read loop - */ - while(XP_FileReadLine(buffer, READ_BUFFER_SIZE, fp)) - { - buffer_ptr = XP_StripLine(buffer); - - if((ptr = strcasestr(buffer_ptr, "HREF=\""))!=0) - { - char *quote, *gtr_than; - /* find next quote - */ - quote = XP_STRCHR(ptr+6, '"'); - - if(quote) - { - *quote = '\0'; - - url = NET_MakeAbsoluteURL(relative_url, ptr+6); - - new_item = HOT_CreateEntry(HOT_URLType, NULL, url, NULL, 0); - item_saved = FALSE; - - XP_FREE(url); - if(!new_item) - return; - - /* find '>' and the name will be right after it - */ - gtr_than = XP_STRCHR(quote+1, '>'); - - if(gtr_than) - { - /* find the end of the name - */ - end = strcasestr(gtr_than, ""); - - if(end) - { - *end = '\0'; - StrAllocCopy(new_item->name, XP_StripLine(gtr_than+1)); - - /* terminate at beginning of name since there - * is nothing interesting after that - */ - *gtr_than = '\0'; - } - else - { - StrAllocCopy(new_item->name, XP_StripLine(gtr_than+1)); - - XP_FileReadLine(buffer_ptr, READ_BUFFER_SIZE, fp); - - end = strcasestr(buffer_ptr, ""); - - if(end) - *end = '\0'; - - StrAllocCat(new_item->name, XP_StripLine(buffer_ptr)); - } - } - - *quote = '"'; - } - } - else if(((ptr = strcasestr(buffer_ptr, "'); - - /* find the end of the name - */ - if(gtr_than) - end = strcasestr(gtr_than, "is_folded = TRUE; - else - new_item->is_folded = FALSE; - - *end = '<'; - } - } - else if((ptr = strcasestr(buffer_ptr, "
    "))!=0) - { - new_item = HOT_CreateEntry(HOT_SeparatorType, NULL, NULL, NULL, 0); - item_saved = FALSE; - } - else if(strcasestr(buffer_ptr, "
") || - strcasestr(buffer_ptr, "") || - strcasestr(buffer_ptr, "")) - { - /* end of a header */ - if(item != hot_list) - return; - } - else - { - /* assume the rest is descriptions - * only add if new_item is a URL - */ - if(new_item && new_item->type == HOT_URLType) - { - /* skip
if present */ - if(*buffer_ptr == '<') - buffer_ptr += 4; - - end = buffer_ptr+XP_STRLEN(buffer_ptr)-1; - - /* check for
on the end and remove it - * - * also add a return - */ - if(*end == '>') - { - end -= 3; - XP_STRCPY(end, LINEBREAK); - end += XP_STRLEN(LINEBREAK); - *end = '\0'; - } - else - { - end++; - XP_STRCPY(end, LINEBREAK); - end += XP_STRLEN(LINEBREAK); - *end = '\0'; - } - - /* go through and turn < into '<' - */ - for(ptr=buffer_ptr, end=buffer_ptr; *end != '\0'; end++) - { - if(!strncasecomp(end, "<", 4)) - { - end += 3; - *ptr++ = '<'; - } - else - { - *ptr++ = *end; - } - } - *ptr = '\0'; /* terminate */ - - StrAllocCat(new_item->description, buffer_ptr); - } - } - - if(new_item) - { - /* search for other general attributes - */ - if((ptr = strcasestr(buffer_ptr, "ADD_DATE=\""))!=0) - { - end = XP_STRCHR(ptr+10, '"'); - - if(end) - { - *end = '\0'; - if(new_item) - new_item->addition_date = (time_t) atol(ptr+10); - *end = '"'; - } - } - - if((ptr = strcasestr(buffer_ptr, "LAST_VISIT=\""))!=0) - { - end = XP_STRCHR(ptr+12, '"'); - - if(end) - { - *end = '\0'; - if(new_item) - new_item->last_visit = (time_t) atol(ptr+12); - *end = '"'; - } - } - - if(!item_saved) - { - if(!item) - { - if(!hot_list) - { - if(new_item->type == HOT_HeaderType) - { - hot_list = new_item; - } - else - { - hot_list = HOT_CreateEntry(HOT_HeaderType, - DEF_NAME, NULL, NULL, 0); - if(!hot_list) - return; - - XP_ListAddObjectToEnd(hot_list->children, new_item); - new_item->parent = NULL; - new_item->lParent = XP_ListFindObject(hot_list->children, new_item); - } - } - - item = hot_list; - } - else - { - XP_ListAddObjectToEnd(item->children, new_item); - if(item == hot_list) - new_item->parent = NULL; - else - new_item->parent = item; - new_item->lParent = XP_ListFindObject(item->children, new_item); - - } - - item_saved = TRUE; - } - - if(new_item->type == HOT_HeaderType) - hot_ReadSaveList(fp, new_item, buffer, relative_url); - } - } -} - -/* read hotlist file from disk - * - * pass in a file url - */ -PUBLIC void -HOT_ReadHotlistFromDisk(char * filename, char * relative_url) -{ - XP_File fp; - char buffer[READ_BUFFER_SIZE]; - - fp = XP_FileOpen(filename, xpHotlist, XP_FILE_READ); - - if(!fp) - { - TRACEMSG(("could not open hotlist file for reading")); - return; - } - - TRACEMSG(("Reading MCC hotlist file")); - -/* DONT REQUIRE THE COOKIE FOR NOW - * - * if(XP_STRNCMP(buffer, HOTLIST_COOKIE, strlen(HOTLIST_COOKIE))) - * { - * TRACEMSG(("ERROR! - Hotlist cookie not found in hotlist file")); - * return; - * } - */ - /* hot_list probably doesn't exist yet - */ - hot_ReadSaveList(fp, hot_list, buffer, relative_url); - XP_FileClose(fp); - hot_list_modified = FALSE; - -} - - -PRIVATE void -hot_PrintList(XP_File fp, HotlistStruct * item, int level) -{ - int i; - char buffer[16]; - - /* indent - */ - for(i=0; itype == HOT_HeaderType) - { - XP_List * list_ptr = item->children; - HotlistStruct * obj_ptr; - - if(level != 0) - { - if(item->name) - { - XP_FileWrite("

is_folded) - XP_FileWrite("FOLDED ", -1, fp); - XP_FileWrite("ADD_DATE=\"", -1, fp); - XP_SPRINTF(buffer, "%ld\">", item->addition_date); - XP_FileWrite(buffer, XP_STRLEN(buffer), fp); - XP_FileWrite(item->name, XP_STRLEN(item->name), fp); - XP_FileWrite("

", -1, fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - } - for(i=0; i

", -1, fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - - while((obj_ptr = (HotlistStruct *) XP_ListNextObject(list_ptr))!=0) - hot_PrintList(fp, obj_ptr, level+1); - - for(i=0; i

", -1, fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - } - else if(item->type == HOT_SeparatorType) - { - XP_FileWrite("


", -1, fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - } - else if(item->address) /* item type */ - { - XP_FileWrite("
", -1, fp); - XP_FileWrite("address, XP_STRLEN(item->address), fp); - XP_FileWrite("\" ADD_DATE=\"", -1, fp); - - XP_SPRINTF(buffer, "%ld", item->addition_date); - XP_FileWrite(buffer, XP_STRLEN(buffer), fp); - - XP_FileWrite("\" LAST_VISIT=\"", -1, fp); - - XP_SPRINTF(buffer, "%ld\">", item->last_visit); - XP_FileWrite(buffer, XP_STRLEN(buffer), fp); - - if(item->name) - XP_FileWrite(item->name, XP_STRLEN(item->name), fp); - else - XP_FileWrite(item->address, XP_STRLEN(item->address), fp); - - XP_FileWrite("", -1, fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - - /* write description if there is one - */ - if(item->description) - { - char *ptr = XP_StripLine(item->description); - - XP_FileWrite("
", -1, fp); - - for(; *ptr != '\0'; ptr++) - if(*ptr == '<') - { - XP_FileWrite("<", -1, fp); - } - else if(*ptr == '\n') - { - XP_FileWrite("
", -1, fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - } - else - { - XP_FileWrite(ptr, 1, fp); - } - - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - } - } -} - -PUBLIC Bool -HOT_Modified (void) -{ - return (hot_list_modified); -} - -/* save out the hotlist - * - * returns 1 on success and 0 on failure - * NOTE: the hotlist may not be saved if nothing has - * changed - */ -PUBLIC int -HOT_SaveHotlist(char * filename) -{ - XP_File fp; - char buffer[128]; - const char * hot_list_name; - - if(!hot_list_modified) - return(1); /* don't rewrite */ - -#ifdef MOZ_MAIL_NEWS - hot_list_name = FE_UsersFullName(); - if(!hot_list_name) - hot_list_name = FE_UsersMailAddress(); -#else - hot_list_name = NULL; -#endif /* MOZ_MAIL_NEWS */ - -#if defined(DEBUG_BOOKMARKS) && defined(XP_UNIX) - fprintf (stderr, "HOT_SaveHotlist: writing %s\n", filename); -#endif - - fp = XP_FileOpen(filename, xpHotlist, XP_FILE_WRITE); - - if(!fp) - { - TRACEMSG(("could not open hotlist file for writing")); - return(0); - } - - /* write cookie - */ - XP_FileWrite(HOTLIST_COOKIE, strlen(HOTLIST_COOKIE), fp); - XP_FileWrite(LINEBREAK, XP_STRLEN(LINEBREAK), fp); - - XP_FileWrite(XP_GetString(XP_HOTLIST_AUTOGENERATED_FILE), -1, fp); - -/* L10N? are we still using this code? */ - XP_SPRINTF(buffer, "\ -%s%s Bookmarks\n\ -

%s%s Bookmarks

\n", hot_list_name ? hot_list_name : "Personal", - hot_list_name ? "'s" : "", - hot_list_name ? hot_list_name : "Personal", - hot_list_name ? "'s" : ""); - - XP_FileWrite(buffer, XP_STRLEN(buffer), fp); - - if(hot_list) - hot_PrintList(fp, hot_list, 0); - else - TRACEMSG(("No hotlist to write!")); - - XP_FileClose(fp); - - hot_list_modified = FALSE; - - return(1); -} - - -/* - * Gets the top node of the hotlist -*/ -PUBLIC HotlistStruct* -HOT_GetHotlist (void) -{ - if (!hot_list) - { - hot_list = HOT_CreateEntry (HOT_HeaderType, DEF_NAME, NULL, NULL, 0); - if (!hot_list) - return NULL; - hot_list->children = XP_ListNew (); - if (!hot_list->children) - { - HOT_FreeEntry(hot_list); - hot_list = NULL; - } - } - return hot_list; -} - -/* Free's the entire hotlist - */ -PUBLIC void -HOT_FreeHotlist (void) -{ - if (hot_list) - HOT_FreeEntry (hot_list); - hot_list = 0; -} diff --git a/mozilla/lib/libmisc/shist.c b/mozilla/lib/libmisc/shist.c index 6df8b9248a8..f32fe032e5e 100644 --- a/mozilla/lib/libmisc/shist.c +++ b/mozilla/lib/libmisc/shist.c @@ -36,15 +36,10 @@ #include "libi18n.h" -#include "hotlist.h" #include "net.h" #include "xp.h" #include "secnav.h" -#if !defined(XP_MAC) && !defined(XP_WIN32) /* macOS doesn't need this anymore... nor does Windows */ - #include "bkmks.h" -#endif - #ifdef EDITOR #include "edt.h" /* for EDT_IS_EDITOR macro */ extern char *XP_NEW_DOC_URL; @@ -246,37 +241,6 @@ SHIST_CreateWysiwygURLStruct(MWContext * ctxt, History_entry * entry) return URL_s; } -/* - * Returns NULL if the entry cannot be a hotlist item (form submission). - */ - -#if !defined(XP_MAC) && !defined(XP_WIN32) /* macOS doesn't need this anymore -- we're 100% RDF! so is windows! */ - -BM_Entry* SHIST_CreateHotlistStructFromHistoryEntry(History_entry * h) -{ - BM_Entry* hs = NULL; - if ((h == NULL) || h->post_data) /* Cannot make form submission into bookmarks */ - return NULL; - - /* if title is empty make the title the URL in the form www.XXX...YYY.html */ - if ( *h->title ) - hs = BM_NewUrl( h->title, h->address, NULL, h->last_access); - else - { - /* Strip off the protocol info (eg, http://) */ - char trunkedAddress [HIST_MAX_URL_LEN + 1]; - char* strippedAddress = SHIST_StripProtocol ( h->address ); - - /* truncate it */ - INTL_MidTruncateString ( 0, strippedAddress, trunkedAddress, HIST_MAX_URL_LEN ); - hs = BM_NewUrl( trunkedAddress, h->address, NULL, h->last_access); - } - - return hs; - -} /* SHIST_CreateHotlistStructFromHistoryEntry */ -#endif - /* * SHIST_StripProtocol *