mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-30 10:12:59 +00:00
* [Feature] Multi-xpi support per checkbox [b=34881]
* Prevent multiple dialogs when consecutive return keys hit [b=36993,36988] * Multiple resource release crash fixes.
This commit is contained in:
parent
3a1856de02
commit
d2456e7938
@ -1,2 +1,3 @@
|
||||
mozilla-installer-bin
|
||||
Makefile
|
||||
xpi
|
||||
|
@ -64,6 +64,7 @@
|
||||
#define MAX_SETUP_TYPES 4
|
||||
#define MAX_URLS 32
|
||||
#define MAX_URL_LEN 1024
|
||||
#define MAX_DEPENDEE_KEY_LEN 16
|
||||
#define MAX_TMP_DIRS 1024
|
||||
|
||||
|
||||
@ -107,6 +108,7 @@
|
||||
#define URLd "URL%d"
|
||||
#define SIZE "Install Size"
|
||||
#define DEPENDENCYd "Dependency%d"
|
||||
#define DEPENDEEd "Dependee%d"
|
||||
#define ATTRIBUTES "Attributes"
|
||||
#define SELECTED_ATTR "SELECTED"
|
||||
#define INVISIBLE_ATTR "INVISIBLE"
|
||||
@ -142,6 +144,13 @@ do { \
|
||||
_ptr = NULL; \
|
||||
} while(0);
|
||||
|
||||
#define XI_GTK_IF_FREE(_gtkWidgetPtr) \
|
||||
do { \
|
||||
if (_gtkWidgetPtr && GTK_IS_WIDGET(_gtkWidgetPtr)) \
|
||||
gtk_widget_destroy(_gtkWidgetPtr); \
|
||||
_gtkWidgetPtr = NULL; \
|
||||
} while(0);
|
||||
|
||||
#define XI_ERR_BAIL(_function) \
|
||||
do { \
|
||||
err = _function; \
|
||||
|
@ -1,7 +1,7 @@
|
||||
;-------------------------------------------------------------------------
|
||||
[General]
|
||||
;-------------------------------------------------------------------------
|
||||
Default Location=/usr/local/mozilla
|
||||
Default Location=/u/sgehani/foo
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
@ -55,6 +55,7 @@ C0=Component0
|
||||
C1=Component1
|
||||
C2=Component2
|
||||
C3=Component3
|
||||
C4=Component4
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
@ -81,6 +82,8 @@ Install Size=2000
|
||||
Attributes=SELECTED
|
||||
URL0=ftp://127.0.0.1/pub/xpi/
|
||||
URL1=ftp://orb.mcom.com/pub/xpi/
|
||||
Dependee0=Browser-UI
|
||||
Dependee1=Java
|
||||
|
||||
[Component2]
|
||||
Description Short=Mail & News
|
||||
@ -100,6 +103,15 @@ Attributes=
|
||||
URL0=ftp://127.0.0.1/pub/xpi/
|
||||
URL1=ftp://orb.mcom.com/pub/xpi/
|
||||
|
||||
[Component4]
|
||||
Description Short=Browser-UI
|
||||
Description Long=Browser User Interface
|
||||
Archive=browser-ui.xpi
|
||||
Install Size=2000
|
||||
Attributes=
|
||||
URL0=ftp://127.0.0.1/pub/xpi/
|
||||
URL1=ftp://orb.mcom.com/pub/xpi/
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
[Dialog Start Install]
|
||||
|
@ -29,16 +29,18 @@ nsComponent::nsComponent() :
|
||||
mDescLong(NULL),
|
||||
mArchive(NULL),
|
||||
mSize(0),
|
||||
mDependencies(NULL),
|
||||
mAttributes(NO_ATTR),
|
||||
mNext(NULL),
|
||||
mIndex(-1),
|
||||
mRefCount(0)
|
||||
mRefCount(0),
|
||||
mDepRefCount(0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_URLS; i++)
|
||||
mURL[i] = NULL;
|
||||
for (i = 0; i < MAX_COMPONENTS; i++)
|
||||
mDependees[i] = NULL;
|
||||
}
|
||||
|
||||
nsComponent::~nsComponent()
|
||||
@ -48,9 +50,10 @@ nsComponent::~nsComponent()
|
||||
XI_IF_FREE(mDescShort);
|
||||
XI_IF_FREE(mDescLong);
|
||||
XI_IF_FREE(mArchive);
|
||||
XI_IF_DELETE(mDependencies)
|
||||
for (i = 0; i < MAX_URLS; i++)
|
||||
XI_IF_FREE(mURL[i]);
|
||||
for (i = 0; i < MAX_COMPONENTS; i++)
|
||||
XI_IF_FREE(mDependees[i]);
|
||||
}
|
||||
|
||||
nsComponent *
|
||||
@ -163,40 +166,45 @@ nsComponent::GetURL(int aIndex)
|
||||
return mURL[aIndex];
|
||||
}
|
||||
|
||||
int
|
||||
nsComponent::AddDependency(nsComponent *aDependent)
|
||||
{
|
||||
if (!aDependent)
|
||||
return E_PARAM;
|
||||
|
||||
if (!mDependencies)
|
||||
mDependencies = new nsComponentList();
|
||||
|
||||
if (!mDependencies)
|
||||
return E_MEM;
|
||||
|
||||
return mDependencies->AddComponent(aDependent);
|
||||
}
|
||||
|
||||
int
|
||||
nsComponent::RemoveDependency(nsComponent *aIndependent)
|
||||
nsComponent::AddDependee(char *aDependee)
|
||||
{
|
||||
if (!aIndependent)
|
||||
if (!aDependee)
|
||||
return E_PARAM;
|
||||
|
||||
if (!mDependencies)
|
||||
return E_NO_MEMBER;
|
||||
mDependees[mNextDependeeIdx] = aDependee;
|
||||
mDependees[++mNextDependeeIdx] = NULL;
|
||||
|
||||
return mDependencies->RemoveComponent(aIndependent);
|
||||
return OK;
|
||||
}
|
||||
|
||||
nsComponentList *
|
||||
nsComponent::GetDependencies()
|
||||
int
|
||||
nsComponent::ResolveDependees(int aBeingSelected, nsComponentList *aComps)
|
||||
{
|
||||
if (mDependencies)
|
||||
return mDependencies;
|
||||
int i;
|
||||
nsComponent *currComp = NULL;
|
||||
|
||||
// param check
|
||||
if (!aComps)
|
||||
return E_PARAM;
|
||||
|
||||
return NULL;
|
||||
// loop over all dependees
|
||||
for (i = 0; i < mNextDependeeIdx; i++)
|
||||
{
|
||||
if (!mDependees[i])
|
||||
break;
|
||||
|
||||
currComp = aComps->GetCompByShortDesc(mDependees[i]);
|
||||
if (!currComp)
|
||||
continue;
|
||||
|
||||
if (aBeingSelected)
|
||||
currComp->DepAddRef();
|
||||
else
|
||||
currComp->DepRelease();
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
@ -212,6 +220,7 @@ nsComponent::SetUnselected()
|
||||
{
|
||||
if (IsSelected())
|
||||
mAttributes &= ~nsComponent::SELECTED;
|
||||
mDepRefCount = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -354,3 +363,34 @@ nsComponent::InitRefCount()
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
nsComponent::DepAddRef()
|
||||
{
|
||||
if (mDepRefCount == 0)
|
||||
SetSelected();
|
||||
|
||||
mDepRefCount++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
nsComponent::DepRelease()
|
||||
{
|
||||
mDepRefCount--;
|
||||
|
||||
if (mDepRefCount < 0)
|
||||
mDepRefCount = 0;
|
||||
|
||||
if (mDepRefCount == 0)
|
||||
SetUnselected();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
nsComponent::DepGetRefCount()
|
||||
{
|
||||
return mDepRefCount;
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ public:
|
||||
int GetSize();
|
||||
int SetURL(char *aURL, int aIndex);
|
||||
char * GetURL(int aIndex);
|
||||
int AddDependency(nsComponent *aDependent);
|
||||
int RemoveDependency(nsComponent *aIndependent);
|
||||
nsComponentList *GetDependencies();
|
||||
int AddDependee(char *aDependee);
|
||||
int ResolveDependees(int aBeingSelected,
|
||||
nsComponentList *aComps);
|
||||
int SetSelected();
|
||||
int SetUnselected();
|
||||
int IsSelected();
|
||||
@ -72,7 +72,12 @@ public:
|
||||
int AddRef();
|
||||
int Release();
|
||||
int InitRefCount();
|
||||
|
||||
|
||||
// used for `dependee' tracking
|
||||
int DepAddRef();
|
||||
int DepRelease();
|
||||
int DepGetRefCount();
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* Attributes
|
||||
*---------------------------------------------------------------*/
|
||||
@ -90,11 +95,13 @@ private:
|
||||
char *mArchive;
|
||||
int mSize;
|
||||
char *mURL[MAX_URLS];
|
||||
nsComponentList *mDependencies;
|
||||
char *mDependees[MAX_COMPONENTS];
|
||||
int mNextDependeeIdx;
|
||||
int mAttributes;
|
||||
nsComponent *mNext;
|
||||
int mIndex;
|
||||
int mRefCount;
|
||||
int mDepRefCount;
|
||||
};
|
||||
|
||||
#endif /* _NS_COMPONENT_H_ */
|
||||
|
@ -243,3 +243,46 @@ nsComponentList::GetCompByArchive(char *aArchive)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsComponent *
|
||||
nsComponentList::GetCompByShortDesc(char *aShortDesc)
|
||||
{
|
||||
nsComponent *comp = GetHead();
|
||||
int i;
|
||||
|
||||
// param check
|
||||
if (!comp || mLength == 0 || !aShortDesc) return NULL;
|
||||
|
||||
for (i=0; i<mLength; i++)
|
||||
{
|
||||
if (0==strncmp(aShortDesc, comp->GetDescShort(),
|
||||
strlen(aShortDesc)))
|
||||
return comp;
|
||||
|
||||
comp = GetNext();
|
||||
if (!comp) break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsComponent *
|
||||
nsComponentList::GetFirstVisible()
|
||||
{
|
||||
int i;
|
||||
nsComponent *comp = GetHead();
|
||||
|
||||
// param check
|
||||
if (mLength == 0) return NULL;
|
||||
|
||||
for (i=0; i<mLength; i++)
|
||||
{
|
||||
if (!comp->IsInvisible())
|
||||
return comp;
|
||||
|
||||
comp = GetNext();
|
||||
if (!comp) break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
/**
|
||||
* GetNext
|
||||
*
|
||||
* Returns the next available item. GetFirst() has to have
|
||||
* Returns the next available item. GetHead() has to have
|
||||
* been called prior calling this and after the last time
|
||||
* the entire list was iterated over.
|
||||
*
|
||||
@ -130,11 +130,32 @@ public:
|
||||
* Searches the list and returns the first component that matches
|
||||
* the archive name supplied.
|
||||
*
|
||||
* @param aArcive the archive name of the component
|
||||
* @param aArchive the archive name of the component
|
||||
* @return comp the component matching the archive
|
||||
*/
|
||||
nsComponent *GetCompByArchive(char *aArchive);
|
||||
|
||||
/**
|
||||
* GetCompByShortDesc
|
||||
*
|
||||
* Searches the list and returns the first component that matches
|
||||
* the short description supplied.
|
||||
*
|
||||
* @param aShortDesc the short description of the component
|
||||
* @return comp the component matching the short description
|
||||
*/
|
||||
nsComponent *GetCompByShortDesc(char *aShortDesc);
|
||||
|
||||
/**
|
||||
* GetFirstVisible
|
||||
*
|
||||
* Returns the first component that doesn't have the invisible
|
||||
* attribute set.
|
||||
*
|
||||
* @return comp the first visible component in this list
|
||||
*/
|
||||
nsComponent *GetFirstVisible();
|
||||
|
||||
private:
|
||||
nsComponent *mHead;
|
||||
nsComponent *mTail;
|
||||
|
@ -93,7 +93,7 @@ nsComponentsDlg::Parse(nsINIParser *aParser)
|
||||
int err = OK;
|
||||
char *showDlg = NULL;
|
||||
int bufsize = 0;
|
||||
int i, j;
|
||||
int i, j, compListLen = 0;
|
||||
|
||||
char *currSec = (char *) malloc(strlen(COMPONENT) + 3);
|
||||
if (!currSec) return E_MEM;
|
||||
@ -103,8 +103,12 @@ nsComponentsDlg::Parse(nsINIParser *aParser)
|
||||
char *currSizeStr = NULL;
|
||||
char *currAttrStr = NULL;
|
||||
char *currURL = NULL;
|
||||
char *currDepName = NULL;
|
||||
char urlKey[MAX_URL_LEN];
|
||||
char dependeeKey[MAX_DEPENDEE_KEY_LEN];
|
||||
nsComponent *currComp = NULL;
|
||||
nsComponent *currDepComp = NULL;
|
||||
nsComponent *currIdxComp = NULL;
|
||||
XI_VERIFY(gCtx);
|
||||
|
||||
/* optional keys */
|
||||
@ -167,7 +171,10 @@ nsComponentsDlg::Parse(nsINIParser *aParser)
|
||||
currComp->SetArchive(currArchive);
|
||||
currComp->SetSize(atoi(currSizeStr));
|
||||
if (NULL != strstr(currAttrStr, SELECTED_ATTR))
|
||||
{
|
||||
currComp->SetSelected();
|
||||
currComp->DepAddRef();
|
||||
}
|
||||
else
|
||||
currComp->SetUnselected();
|
||||
if (NULL != strstr(currAttrStr, INVISIBLE_ATTR))
|
||||
@ -194,15 +201,51 @@ nsComponentsDlg::Parse(nsINIParser *aParser)
|
||||
XI_ERR_BAIL(mCompList->AddComponent(currComp));
|
||||
}
|
||||
|
||||
if (0 == mCompList->GetLength())
|
||||
compListLen = mCompList->GetLength();
|
||||
if (0 == compListLen)
|
||||
{
|
||||
XI_IF_DELETE(mCompList);
|
||||
err = E_NO_COMPONENTS;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
return err;
|
||||
// now parse dependee list for all components
|
||||
for (i = 0; i < compListLen; i++)
|
||||
{
|
||||
memset(currSec, 0, strlen(COMPONENT) + 3);
|
||||
sprintf(currSec, COMPONENTd, i);
|
||||
|
||||
currIdxComp = mCompList->GetCompByIndex(i);
|
||||
if (!currIdxComp)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MAX_COMPONENTS; j++)
|
||||
{
|
||||
currDepComp = NULL;
|
||||
memset(dependeeKey, 0, MAX_DEPENDEE_KEY_LEN);
|
||||
sprintf(dependeeKey, DEPENDEEd, j);
|
||||
|
||||
err = aParser->GetStringAlloc(currSec, dependeeKey,
|
||||
&currDepName, &bufsize);
|
||||
if (bufsize == 0 || err != nsINIParser::OK || !currDepName)
|
||||
{
|
||||
err = OK;
|
||||
break; // no more dependees
|
||||
}
|
||||
|
||||
currDepComp = mCompList->GetCompByShortDesc(currDepName);
|
||||
if (!currDepComp) // unexpected dependee name
|
||||
continue;
|
||||
currDepComp->SetSelected();
|
||||
currDepComp->DepAddRef();
|
||||
|
||||
currIdxComp->AddDependee(currDepName);
|
||||
}
|
||||
}
|
||||
|
||||
BAIL:
|
||||
XI_IF_FREE(currSec);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -319,7 +362,7 @@ nsComponentsDlg::Show(int aDirection)
|
||||
gtk_widget_show(frame);
|
||||
|
||||
sDescLong = gtk_label_new(
|
||||
sCustomST->GetComponents()->GetHead()->GetDescLong());
|
||||
sCustomST->GetComponents()->GetFirstVisible()->GetDescLong());
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), sDescLong, FALSE, FALSE, 20);
|
||||
gtk_widget_show(hbox);
|
||||
@ -429,29 +472,50 @@ nsComponentsDlg::RowSelected(GtkWidget *aWidget, gint aRow, gint aColumn,
|
||||
{
|
||||
if (!currComp->IsInvisible())
|
||||
{
|
||||
if (aRow == currRow)
|
||||
{
|
||||
// update long desc
|
||||
gtk_label_set_text(GTK_LABEL(sDescLong),
|
||||
currComp->GetDescLong());
|
||||
gtk_widget_show(sDescLong);
|
||||
if (aRow == currRow)
|
||||
{
|
||||
// update long desc
|
||||
gtk_label_set_text(GTK_LABEL(sDescLong),
|
||||
currComp->GetDescLong());
|
||||
gtk_widget_show(sDescLong);
|
||||
|
||||
if (currComp->IsSelected())
|
||||
{
|
||||
DUMP("Toggling off...");
|
||||
currComp->SetUnselected();
|
||||
gtk_clist_set_pixmap(GTK_CLIST(aWidget), currRow, 0,
|
||||
unchecked, un_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DUMP("Toggling on...");
|
||||
currComp->SetSelected();
|
||||
gtk_clist_set_pixmap(GTK_CLIST(aWidget), currRow, 0,
|
||||
checked, ch_mask);
|
||||
}
|
||||
if (currComp->IsSelected())
|
||||
{
|
||||
DUMP("Toggling off...");
|
||||
currComp->SetUnselected();
|
||||
}
|
||||
currRow++;
|
||||
else
|
||||
{
|
||||
DUMP("Toggling on...");
|
||||
currComp->SetSelected();
|
||||
}
|
||||
currComp->ResolveDependees(currComp->IsSelected(),
|
||||
sCustomST->GetComponents());
|
||||
break;
|
||||
}
|
||||
currRow++;
|
||||
}
|
||||
currComp = currComp->GetNext();
|
||||
}
|
||||
|
||||
// after resolving dependees redraw all checkboxes in one fell swoop
|
||||
currRow = 0;
|
||||
currComp = sCustomST->GetComponents()->GetHead();
|
||||
while ((currRow < numRows) && currComp) // paranoia!
|
||||
{
|
||||
if (!currComp->IsInvisible())
|
||||
{
|
||||
if (currComp->IsSelected())
|
||||
{
|
||||
gtk_clist_set_pixmap(GTK_CLIST(aWidget), currRow, 0,
|
||||
checked, ch_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_clist_set_pixmap(GTK_CLIST(aWidget), currRow, 0,
|
||||
unchecked, un_mask);
|
||||
}
|
||||
currRow++;
|
||||
}
|
||||
currComp = currComp->GetNext();
|
||||
}
|
||||
|
@ -526,6 +526,9 @@ nsSetupTypeDlg::SelectFolder(GtkWidget *aWidget, gpointer aData)
|
||||
{
|
||||
DUMP("SelectFolder");
|
||||
|
||||
if (sFilePickerUp)
|
||||
return;
|
||||
|
||||
GtkWidget *fileSel = NULL;
|
||||
char *selDir = gCtx->opt->mDestination;
|
||||
|
||||
|
@ -46,6 +46,8 @@ nsXIContext::nsXIContext()
|
||||
declineLabel = NULL;
|
||||
installLabel = NULL;
|
||||
logo = NULL;
|
||||
canvas = NULL;
|
||||
notebook = NULL;
|
||||
|
||||
backID = 0;
|
||||
nextID = 0;
|
||||
@ -67,16 +69,19 @@ nsXIContext::~nsXIContext()
|
||||
|
||||
XI_IF_DELETE(opt);
|
||||
|
||||
XI_IF_FREE(window);
|
||||
XI_IF_FREE(back);
|
||||
XI_IF_FREE(next);
|
||||
XI_IF_FREE(cancel);
|
||||
XI_IF_FREE(nextLabel);
|
||||
XI_IF_FREE(backLabel);
|
||||
XI_IF_FREE(acceptLabel);
|
||||
XI_IF_FREE(declineLabel);
|
||||
XI_IF_FREE(installLabel);
|
||||
XI_IF_FREE(logo);
|
||||
XI_GTK_IF_FREE(back);
|
||||
XI_GTK_IF_FREE(next);
|
||||
XI_GTK_IF_FREE(cancel);
|
||||
XI_GTK_IF_FREE(nextLabel);
|
||||
XI_GTK_IF_FREE(backLabel);
|
||||
XI_GTK_IF_FREE(acceptLabel);
|
||||
XI_GTK_IF_FREE(declineLabel);
|
||||
XI_GTK_IF_FREE(installLabel);
|
||||
XI_GTK_IF_FREE(logo);
|
||||
XI_GTK_IF_FREE(mainbox);
|
||||
XI_GTK_IF_FREE(canvas);
|
||||
XI_GTK_IF_FREE(notebook);
|
||||
XI_GTK_IF_FREE(window);
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -32,5 +32,4 @@ nsXIOptions::nsXIOptions() :
|
||||
|
||||
nsXIOptions::~nsXIOptions()
|
||||
{
|
||||
XI_IF_FREE(mDestination);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user