зеркало из https://github.com/mozilla/gecko-dev.git
Adding new files for C++ rewrite of filepicker. Not part of the build.
This commit is contained in:
Родитель
64680b4760
Коммит
0ac7672293
|
@ -0,0 +1,52 @@
|
|||
#! gmake
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Brian Ryner <bryner@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = filepicker
|
||||
XPIDL_MODULE = filepicker
|
||||
|
||||
XPIDLSRCS = nsIFileView.idl
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#!nmake
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Brian Ryner <bryner@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE= filepicker
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
XPIDLSRCS= .\nsIFileView.idl
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(60b320d2-1dd2-11b2-bd73-dc3575f78ddd)]
|
||||
interface nsIFileView : nsISupports
|
||||
{
|
||||
const short sortName = 0;
|
||||
const short sortSize = 1;
|
||||
const short sortDate = 2;
|
||||
|
||||
attribute boolean showHiddenFiles;
|
||||
attribute boolean showOnlyDirectories;
|
||||
readonly attribute short sortType;
|
||||
readonly attribute boolean reverseSort;
|
||||
|
||||
void sort(in short sortType, in boolean reverseSort);
|
||||
void setDirectory(in nsIFile directory);
|
||||
void setFilter(in wstring filterString);
|
||||
|
||||
nsIFile getSelectedFile();
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
#define NS_FILEVIEW_CONTRACTID "@mozilla.org/filepicker/fileview;1"
|
||||
|
||||
%}
|
|
@ -0,0 +1,761 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communicationsm Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIFileView.h"
|
||||
#include "nsIOutlinerView.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIOutlinerSelection.h"
|
||||
#include "nsIOutlinerBoxObject.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "prmem.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIDateTimeFormat.h"
|
||||
#include "nsDateTimeFormatCID.h"
|
||||
#include "nsQuickSort.h"
|
||||
|
||||
#include "nsWildCard.h"
|
||||
|
||||
#define NS_FILEVIEW_CID { 0xa5570462, 0x1dd1, 0x11b2, \
|
||||
{ 0x9d, 0x19, 0xdf, 0x30, 0xa2, 0x7f, 0xbd, 0xc4 } }
|
||||
|
||||
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
|
||||
|
||||
class nsFileView : public nsIFileView,
|
||||
public nsIOutlinerView
|
||||
{
|
||||
public:
|
||||
nsFileView();
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFILEVIEW
|
||||
NS_DECL_NSIOUTLINERVIEW
|
||||
|
||||
protected:
|
||||
virtual ~nsFileView();
|
||||
|
||||
PRInt32 FilterFiles();
|
||||
void ReverseArray(nsISupportsArray* aArray);
|
||||
void SortArray(nsISupportsArray* aArray);
|
||||
void SortInternal();
|
||||
|
||||
nsCOMPtr<nsISupportsArray> mFileList;
|
||||
nsCOMPtr<nsISupportsArray> mDirList;
|
||||
nsCOMPtr<nsISupportsArray> mFilteredFiles;
|
||||
|
||||
nsCOMPtr<nsIFile> mDirectoryPath;
|
||||
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
|
||||
nsCOMPtr<nsIOutlinerSelection> mSelection;
|
||||
nsCOMPtr<nsIAtom> mDirectoryAtom;
|
||||
nsCOMPtr<nsIAtom> mFileAtom;
|
||||
nsCOMPtr<nsIDateTimeFormat> mDateFormatter;
|
||||
|
||||
PRInt16 mSortType;
|
||||
PRInt32 mTotalRows;
|
||||
|
||||
nsVoidArray mCurrentFilters;
|
||||
|
||||
PRPackedBool mShowHiddenFiles;
|
||||
PRPackedBool mDirectoryFilter;
|
||||
PRPackedBool mReverseSort;
|
||||
};
|
||||
|
||||
// Factory constructor
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFileView, Init)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "nsFileView", NS_FILEVIEW_CID,
|
||||
NS_FILEVIEW_CONTRACTID, nsFileViewConstructor }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(nsFileViewModule, components);
|
||||
|
||||
|
||||
nsFileView::nsFileView() :
|
||||
mSortType(-1),
|
||||
mTotalRows(0),
|
||||
mShowHiddenFiles(PR_FALSE),
|
||||
mDirectoryFilter(PR_FALSE),
|
||||
mReverseSort(PR_FALSE)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsFileView::~nsFileView()
|
||||
{
|
||||
PRInt32 count = mCurrentFilters.Count();
|
||||
for (PRInt32 i = 0; i < count; ++i)
|
||||
PR_Free(mCurrentFilters[i]);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFileView::Init()
|
||||
{
|
||||
mDirectoryAtom = NS_NewAtom("directory");
|
||||
mFileAtom = NS_NewAtom("file");
|
||||
NS_NewISupportsArray(getter_AddRefs(mFileList));
|
||||
NS_NewISupportsArray(getter_AddRefs(mDirList));
|
||||
NS_NewISupportsArray(getter_AddRefs(mFilteredFiles));
|
||||
mDateFormatter = do_CreateInstance(kDateTimeFormatCID);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsISupports implementation
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsFileView)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFileView)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFileView)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIOutlinerView)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(nsFileView)
|
||||
NS_IMPL_RELEASE(nsFileView)
|
||||
|
||||
|
||||
// nsIFileView implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetShowHiddenFiles(PRBool aShowHidden)
|
||||
{
|
||||
mShowHiddenFiles = aShowHidden;
|
||||
|
||||
// This could be better optimized, but since the hidden
|
||||
// file functionality is not currently used, this will be fine.
|
||||
SetDirectory(mDirectoryPath);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetShowHiddenFiles(PRBool* aShowHidden)
|
||||
{
|
||||
*aShowHidden = mShowHiddenFiles;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetShowOnlyDirectories(PRBool aOnlyDirs)
|
||||
{
|
||||
if (aOnlyDirs == mDirectoryFilter)
|
||||
return NS_OK;
|
||||
|
||||
mDirectoryFilter = aOnlyDirs;
|
||||
PRUint32 dirCount;
|
||||
mDirList->Count(&dirCount);
|
||||
if (mDirectoryFilter) {
|
||||
PRInt32 rowDiff = mTotalRows - dirCount;
|
||||
|
||||
mFilteredFiles->Clear();
|
||||
mTotalRows = dirCount;
|
||||
if (mOutliner)
|
||||
mOutliner->RowCountChanged(mTotalRows, -rowDiff);
|
||||
} else {
|
||||
// Run the filter again to get the file list back
|
||||
PRInt32 rowsAdded = FilterFiles();
|
||||
if (rowsAdded)
|
||||
mOutliner->RowCountChanged(dirCount, rowsAdded);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetShowOnlyDirectories(PRBool* aOnlyDirs)
|
||||
{
|
||||
*aOnlyDirs = mDirectoryFilter;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetSortType(PRInt16* aSortType)
|
||||
{
|
||||
*aSortType = mSortType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetReverseSort(PRBool* aReverseSort)
|
||||
{
|
||||
*aReverseSort = mReverseSort;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::Sort(PRInt16 aSortType, PRBool aReverseSort)
|
||||
{
|
||||
if (aSortType == mSortType) {
|
||||
if (aReverseSort != mReverseSort) {
|
||||
mReverseSort = aReverseSort;
|
||||
ReverseArray(mDirList);
|
||||
ReverseArray(mFilteredFiles);
|
||||
} else
|
||||
return NS_OK;
|
||||
} else {
|
||||
mSortType = aSortType;
|
||||
mReverseSort = aReverseSort;
|
||||
SortInternal();
|
||||
}
|
||||
|
||||
if (mOutliner)
|
||||
mOutliner->Invalidate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetDirectory(nsIFile* aDirectory)
|
||||
{
|
||||
mDirectoryPath = aDirectory;
|
||||
mFileList->Clear();
|
||||
mDirList->Clear();
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> dirEntries;
|
||||
mDirectoryPath->GetDirectoryEntries(getter_AddRefs(dirEntries));
|
||||
PRBool hasMore = PR_FALSE;
|
||||
PRInt32 dirCount = 0, fileCount = 0;
|
||||
|
||||
while (NS_SUCCEEDED(dirEntries->HasMoreElements(&hasMore)) && hasMore) {
|
||||
nsCOMPtr<nsISupports> nextItem;
|
||||
dirEntries->GetNext(getter_AddRefs(nextItem));
|
||||
nsCOMPtr<nsIFile> theFile = do_QueryInterface(nextItem);
|
||||
|
||||
PRBool isDirectory;
|
||||
theFile->IsDirectory(&isDirectory);
|
||||
|
||||
if (isDirectory) {
|
||||
PRBool isHidden;
|
||||
theFile->IsHidden(&isHidden);
|
||||
if (mShowHiddenFiles || !isHidden) {
|
||||
mDirList->AppendElement(theFile);
|
||||
++dirCount;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mFileList->AppendElement(theFile);
|
||||
++fileCount;
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 oldRows = mTotalRows;
|
||||
|
||||
FilterFiles();
|
||||
SortInternal();
|
||||
|
||||
if (mOutliner) {
|
||||
mOutliner->RowCountChanged(0, -oldRows);
|
||||
mOutliner->RowCountChanged(0, mTotalRows);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetFilter(const PRUnichar* aFilterString)
|
||||
{
|
||||
PRInt32 filterCount = mCurrentFilters.Count();
|
||||
for (PRInt32 i = 0; i < filterCount; ++i)
|
||||
PR_Free(mCurrentFilters[i]);
|
||||
mCurrentFilters.Clear();
|
||||
|
||||
const PRUnichar* chr, *aPos = aFilterString;
|
||||
for (chr = aFilterString; *chr; ++chr) {
|
||||
if (*chr == ';') {
|
||||
PRUnichar* aNewString = nsCRT::strndup(aPos, (chr - aPos));
|
||||
mCurrentFilters.AppendElement(aNewString);
|
||||
|
||||
// ; will be followed by a space, and then the next filter
|
||||
chr += 2;
|
||||
aPos = chr;
|
||||
}
|
||||
}
|
||||
|
||||
if ((aPos < chr) && *aPos) {
|
||||
PRUnichar* aNewString = nsCRT::strndup(aPos, (chr - aPos));
|
||||
mCurrentFilters.AppendElement(aNewString);
|
||||
}
|
||||
|
||||
mFilteredFiles->Clear();
|
||||
|
||||
PRUint32 dirCount;
|
||||
mDirList->Count(&dirCount);
|
||||
PRInt32 oldFileRows = mTotalRows - dirCount;
|
||||
PRInt32 newFileRows = FilterFiles();
|
||||
|
||||
SortArray(mFilteredFiles);
|
||||
if (mReverseSort)
|
||||
ReverseArray(mFilteredFiles);
|
||||
|
||||
if (mOutliner) {
|
||||
mOutliner->RowCountChanged(dirCount, newFileRows - oldFileRows);
|
||||
|
||||
PRInt32 commonRange = PR_MIN(newFileRows, oldFileRows);
|
||||
if (commonRange)
|
||||
mOutliner->InvalidateRange(dirCount, dirCount + commonRange);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetSelectedFile(nsIFile** aFile)
|
||||
{
|
||||
*aFile = nsnull;
|
||||
|
||||
PRInt32 currentIndex;
|
||||
mSelection->GetCurrentIndex(¤tIndex);
|
||||
|
||||
if (0 <= currentIndex) {
|
||||
PRUint32 dirCount;
|
||||
mDirList->Count(&dirCount);
|
||||
if (currentIndex < (PRInt32) dirCount) {
|
||||
nsCOMPtr<nsISupports> elem = dont_AddRef(mDirList->ElementAt(currentIndex));
|
||||
CallQueryInterface(elem, aFile);
|
||||
} else {
|
||||
PRUint32 fileCount;
|
||||
mFilteredFiles->Count(&fileCount);
|
||||
if ((currentIndex - dirCount) < fileCount) {
|
||||
nsCOMPtr<nsISupports> elem = dont_AddRef(mFilteredFiles->ElementAt(currentIndex - dirCount));
|
||||
CallQueryInterface(elem, aFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// nsIOutlinerView implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetRowCount(PRInt32* aRowCount)
|
||||
{
|
||||
*aRowCount = mTotalRows;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetSelection(nsIOutlinerSelection** aSelection)
|
||||
{
|
||||
*aSelection = mSelection;
|
||||
NS_IF_ADDREF(*aSelection);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetSelection(nsIOutlinerSelection* aSelection)
|
||||
{
|
||||
mSelection = aSelection;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetRowProperties(PRInt32 aIndex,
|
||||
nsISupportsArray* aProperties)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetCellProperties(PRInt32 aRow, const PRUnichar* aColID,
|
||||
nsISupportsArray* aProperties)
|
||||
{
|
||||
PRUint32 dirCount;
|
||||
mDirList->Count(&dirCount);
|
||||
PRUint32 fileCount;
|
||||
mFilteredFiles->Count(&fileCount);
|
||||
|
||||
if (aRow < (PRInt32) dirCount)
|
||||
aProperties->AppendElement(mDirectoryAtom);
|
||||
else if ((aRow - dirCount) < fileCount)
|
||||
aProperties->AppendElement(mFileAtom);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetColumnProperties(const PRUnichar* aColID,
|
||||
nsIDOMElement* aColElement,
|
||||
nsISupportsArray* aProperties)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::IsContainer(PRInt32 aIndex, PRBool* aIsContainer)
|
||||
{
|
||||
*aIsContainer = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::IsContainerOpen(PRInt32 aIndex, PRBool* aIsOpen)
|
||||
{
|
||||
*aIsOpen = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::IsContainerEmpty(PRInt32 aIndex, PRBool* aIsEmpty)
|
||||
{
|
||||
*aIsEmpty = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::IsSeparator(PRInt32 aIndex, PRBool* aIsSeparator)
|
||||
{
|
||||
*aIsSeparator = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::IsSorted(PRBool* aIsSorted)
|
||||
{
|
||||
*aIsSorted = (mSortType >= 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::CanDropOn(PRInt32 aIndex, PRBool* aCanDrop)
|
||||
{
|
||||
*aCanDrop = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::CanDropBeforeAfter(PRInt32 aIndex, PRBool aBefore,
|
||||
PRBool* aCanDrop)
|
||||
{
|
||||
*aCanDrop = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::Drop(PRInt32 aRow, PRInt32 aOrientation)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetParentIndex(PRInt32 aRowIndex, PRInt32* aParentIndex)
|
||||
{
|
||||
*aParentIndex = -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::HasNextSibling(PRInt32 aRowIndex, PRInt32 aAfterIndex,
|
||||
PRBool* aHasSibling)
|
||||
{
|
||||
*aHasSibling = (aAfterIndex < (mTotalRows - 1));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetLevel(PRInt32 aIndex, PRInt32* aLevel)
|
||||
{
|
||||
*aLevel = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::GetCellText(PRInt32 aRow, const PRUnichar* aColID,
|
||||
PRUnichar** aCellText)
|
||||
{
|
||||
PRUint32 dirCount, fileCount;
|
||||
mDirList->Count(&dirCount);
|
||||
mFilteredFiles->Count(&fileCount);
|
||||
|
||||
PRBool isDirectory;
|
||||
nsCOMPtr<nsIFile> curFile;
|
||||
|
||||
if (aRow < (PRInt32) dirCount) {
|
||||
isDirectory = PR_TRUE;
|
||||
curFile = do_QueryElementAt(mDirList, aRow);
|
||||
} else if ((aRow - dirCount) < fileCount) {
|
||||
isDirectory = PR_FALSE;
|
||||
curFile = do_QueryElementAt(mFilteredFiles, aRow - dirCount);
|
||||
} else {
|
||||
// invalid row
|
||||
*aCellText = ToNewUnicode(NS_LITERAL_STRING(""));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_LITERAL_STRING("FilenameColumn").Equals(aColID)) {
|
||||
curFile->GetUnicodeLeafName(aCellText);
|
||||
} else if (NS_LITERAL_STRING("LastModifiedColumn").Equals(aColID)) {
|
||||
PRInt64 lastModDate;
|
||||
curFile->GetLastModificationDate(&lastModDate);
|
||||
nsAutoString dateString;
|
||||
mDateFormatter->FormatPRTime(nsnull, kDateFormatShort, kTimeFormatSeconds,
|
||||
lastModDate * 1000, dateString);
|
||||
*aCellText = ToNewUnicode(dateString);
|
||||
} else if (NS_LITERAL_STRING("FileSizeColumn").Equals(aColID)) {
|
||||
if (isDirectory)
|
||||
*aCellText = ToNewUnicode(NS_LITERAL_STRING(""));
|
||||
else {
|
||||
PRInt64 fileSize;
|
||||
curFile->GetFileSize(&fileSize);
|
||||
*aCellText = ToNewUnicode(nsPrintfCString("%lld", fileSize));
|
||||
}
|
||||
} else
|
||||
*aCellText = ToNewUnicode(NS_LITERAL_STRING(""));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetOutliner(nsIOutlinerBoxObject* aOutliner)
|
||||
{
|
||||
mOutliner = aOutliner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::ToggleOpenState(PRInt32 aIndex)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::CycleHeader(const PRUnichar* aColID, nsIDOMElement* aElement)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SelectionChanged()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::CycleCell(PRInt32 aRow, const PRUnichar* aColID)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::IsEditable(PRInt32 aRow, const PRUnichar* aColID,
|
||||
PRBool* aIsEditable)
|
||||
{
|
||||
*aIsEditable = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::SetCellText(PRInt32 aRow, const PRUnichar* aColID,
|
||||
const PRUnichar* aValue)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::PerformAction(const PRUnichar* aAction)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::PerformActionOnRow(const PRUnichar* aAction, PRInt32 aRow)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileView::PerformActionOnCell(const PRUnichar* aAction, PRInt32 aRow,
|
||||
const PRUnichar* aColID)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
PRInt32
|
||||
nsFileView::FilterFiles()
|
||||
{
|
||||
PRUint32 count = 0, filteredFiles = 0;
|
||||
mFileList->Count(&count);
|
||||
mFilteredFiles->Clear();
|
||||
PRInt32 filterCount = mCurrentFilters.Count();
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIFile> aFile = do_QueryElementAt(mFileList, i);
|
||||
PRBool isHidden = PR_FALSE;
|
||||
if (!mShowHiddenFiles)
|
||||
aFile->IsHidden(&isHidden);
|
||||
|
||||
nsXPIDLString unicodeLeafName;
|
||||
aFile->GetUnicodeLeafName(getter_Copies(unicodeLeafName));
|
||||
|
||||
if (!isHidden) {
|
||||
for (PRInt32 i = 0; i < filterCount; ++i) {
|
||||
if (NS_WildCardMatch(unicodeLeafName.get(),
|
||||
(const PRUnichar*) mCurrentFilters.ElementAt(i),
|
||||
PR_TRUE) == MATCH) {
|
||||
mFilteredFiles->AppendElement(aFile);
|
||||
++filteredFiles;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mDirList->Count(&count);
|
||||
mTotalRows = count + filteredFiles;
|
||||
return filteredFiles;
|
||||
}
|
||||
|
||||
void
|
||||
nsFileView::ReverseArray(nsISupportsArray* aArray)
|
||||
{
|
||||
PRUint32 count;
|
||||
aArray->Count(&count);
|
||||
for (PRUint32 i = 0; i < count/2; ++i) {
|
||||
nsCOMPtr<nsISupports> element = dont_AddRef(aArray->ElementAt(i));
|
||||
nsCOMPtr<nsISupports> element2 = dont_AddRef(aArray->ElementAt(count-i-1));
|
||||
aArray->ReplaceElementAt(element2, i);
|
||||
aArray->ReplaceElementAt(element, count-i-1);
|
||||
}
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
SortNameCallback(const void* aElement1, const void* aElement2, void* aContext)
|
||||
{
|
||||
nsIFile* file1 = *NS_STATIC_CAST(nsIFile* const *, aElement1);
|
||||
nsIFile* file2 = *NS_STATIC_CAST(nsIFile* const *, aElement2);
|
||||
|
||||
nsXPIDLString leafName1, leafName2;
|
||||
file1->GetUnicodeLeafName(getter_Copies(leafName1));
|
||||
file2->GetUnicodeLeafName(getter_Copies(leafName2));
|
||||
|
||||
return nsCRT::strcmp(leafName1.get(), leafName2.get());
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
SortSizeCallback(const void* aElement1, const void* aElement2, void* aContext)
|
||||
{
|
||||
nsIFile* file1 = *NS_STATIC_CAST(nsIFile* const *, aElement1);
|
||||
nsIFile* file2 = *NS_STATIC_CAST(nsIFile* const *, aElement2);
|
||||
|
||||
PRInt64 size1, size2;
|
||||
file1->GetFileSize(&size1);
|
||||
file2->GetFileSize(&size2);
|
||||
|
||||
if (LL_EQ(size1, size2))
|
||||
return 0;
|
||||
|
||||
return (LL_CMP(size1, <, size2) ? -1 : 1);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
SortDateCallback(const void* aElement1, const void* aElement2, void* aContext)
|
||||
{
|
||||
nsIFile* file1 = *NS_STATIC_CAST(nsIFile* const *, aElement1);
|
||||
nsIFile* file2 = *NS_STATIC_CAST(nsIFile* const *, aElement2);
|
||||
|
||||
PRInt64 date1, date2;
|
||||
file1->GetLastModificationDate(&date1);
|
||||
file2->GetLastModificationDate(&date2);
|
||||
|
||||
if (LL_EQ(date1, date2))
|
||||
return 0;
|
||||
|
||||
return (LL_CMP(date1, <, date2) ? -1 : 1);
|
||||
}
|
||||
|
||||
void
|
||||
nsFileView::SortArray(nsISupportsArray* aArray)
|
||||
{
|
||||
// We assume the array to be in filesystem order, which
|
||||
// for our purposes, is completely unordered.
|
||||
|
||||
int (*compareFunc)(const void*, const void*, void*);
|
||||
|
||||
switch (mSortType) {
|
||||
case sortName:
|
||||
compareFunc = SortNameCallback;
|
||||
break;
|
||||
case sortSize:
|
||||
compareFunc = SortSizeCallback;
|
||||
break;
|
||||
case sortDate:
|
||||
compareFunc = SortDateCallback;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 count;
|
||||
aArray->Count(&count);
|
||||
|
||||
// each item will have an additional refcount while
|
||||
// the array is alive.
|
||||
nsIFile** array = new nsIFile*[count];
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsISupports> item = aArray->ElementAt(i);
|
||||
CallQueryInterface(item, &(array[i]));
|
||||
}
|
||||
|
||||
NS_QuickSort(array, count, sizeof(nsIFile*), compareFunc, nsnull);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
aArray->ReplaceElementAt(array[i], i);
|
||||
NS_RELEASE(array[i]);
|
||||
}
|
||||
|
||||
delete[] array;
|
||||
}
|
||||
|
||||
void
|
||||
nsFileView::SortInternal()
|
||||
{
|
||||
SortArray(mDirList);
|
||||
SortArray(mFilteredFiles);
|
||||
|
||||
if (mReverseSort) {
|
||||
ReverseArray(mDirList);
|
||||
ReverseArray(mFilteredFiles);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,296 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* *
|
||||
*
|
||||
*
|
||||
* shexp.c: shell-like wildcard match routines
|
||||
*
|
||||
* See shexp.h for public documentation.
|
||||
*
|
||||
* Rob McCool
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsWildCard.h"
|
||||
#include "nsCRT.h"
|
||||
#include "plstr.h"
|
||||
#include "prmem.h"
|
||||
|
||||
/* ----------------------------- shexp_valid ------------------------------ */
|
||||
|
||||
|
||||
static int
|
||||
_valid_subexp(PRUnichar *expr, PRUnichar stop)
|
||||
{
|
||||
register int x,y,t;
|
||||
int nsc,np,tld;
|
||||
|
||||
x=0;nsc=0;tld=0;
|
||||
|
||||
while(expr[x] && (expr[x] != stop)) {
|
||||
switch(expr[x]) {
|
||||
case '~':
|
||||
if(tld) return INVALID_SXP;
|
||||
else ++tld;
|
||||
case '*':
|
||||
case '?':
|
||||
case '^':
|
||||
case '$':
|
||||
++nsc;
|
||||
break;
|
||||
case '[':
|
||||
++nsc;
|
||||
if((!expr[++x]) || (expr[x] == ']'))
|
||||
return INVALID_SXP;
|
||||
for(++x;expr[x] && (expr[x] != ']');++x)
|
||||
if(expr[x] == '\\')
|
||||
if(!expr[++x])
|
||||
return INVALID_SXP;
|
||||
if(!expr[x])
|
||||
return INVALID_SXP;
|
||||
break;
|
||||
case '(':
|
||||
++nsc;np = 0;
|
||||
while(1) {
|
||||
if(expr[++x] == ')')
|
||||
return INVALID_SXP;
|
||||
for(y=x;(expr[y]) && (expr[y] != '|') && (expr[y] != ')');++y)
|
||||
if(expr[y] == '\\')
|
||||
if(!expr[++y])
|
||||
return INVALID_SXP;
|
||||
if(!expr[y])
|
||||
return INVALID_SXP;
|
||||
if(expr[y] == '|')
|
||||
++np;
|
||||
t = _valid_subexp(&expr[x],expr[y]);
|
||||
if(t == INVALID_SXP)
|
||||
return INVALID_SXP;
|
||||
x+=t;
|
||||
if(expr[x] == ')') {
|
||||
if(!np)
|
||||
return INVALID_SXP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
return INVALID_SXP;
|
||||
case '\\':
|
||||
if(!expr[++x])
|
||||
return INVALID_SXP;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
if((!stop) && (!nsc))
|
||||
return NON_SXP;
|
||||
return ((expr[x] == stop) ? x : INVALID_SXP);
|
||||
}
|
||||
|
||||
int
|
||||
NS_WildCardValid(PRUnichar *expr)
|
||||
{
|
||||
int x;
|
||||
|
||||
x = _valid_subexp(expr, '\0');
|
||||
return (x < 0 ? x : VALID_SXP);
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------- shexp_match ----------------------------- */
|
||||
|
||||
|
||||
#define MATCH 0
|
||||
#define NOMATCH 1
|
||||
#define ABORTED -1
|
||||
|
||||
static int _shexp_match(const PRUnichar *str, const PRUnichar *expr,
|
||||
PRBool case_insensitive);
|
||||
|
||||
static int
|
||||
_handle_union(const PRUnichar *str, const PRUnichar *expr,
|
||||
PRBool case_insensitive)
|
||||
{
|
||||
PRUnichar *e2 = (PRUnichar *) PR_Malloc(sizeof(PRUnichar)*nsCRT::strlen(expr));
|
||||
register int t,p2,p1 = 1;
|
||||
int cp;
|
||||
|
||||
while(1) {
|
||||
for(cp=1;expr[cp] != ')';cp++)
|
||||
if(expr[cp] == '\\')
|
||||
++cp;
|
||||
for(p2 = 0;(expr[p1] != '|') && (p1 != cp);p1++,p2++) {
|
||||
if(expr[p1] == '\\')
|
||||
e2[p2++] = expr[p1++];
|
||||
e2[p2] = expr[p1];
|
||||
}
|
||||
for (t=cp+1; ((e2[p2] = expr[t]) != 0); ++t,++p2) {}
|
||||
if(_shexp_match(str,e2, case_insensitive) == MATCH) {
|
||||
PR_Free(e2);
|
||||
return MATCH;
|
||||
}
|
||||
if(p1 == cp) {
|
||||
PR_Free(e2);
|
||||
return NOMATCH;
|
||||
}
|
||||
else ++p1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_shexp_match(const PRUnichar *str, const PRUnichar *expr,
|
||||
PRBool case_insensitive)
|
||||
{
|
||||
register int x,y;
|
||||
int ret,neg;
|
||||
|
||||
ret = 0;
|
||||
for(x=0,y=0;expr[y];++y,++x) {
|
||||
if((!str[x]) && (expr[y] != '(') && (expr[y] != '$') && (expr[y] != '*'))
|
||||
ret = ABORTED;
|
||||
else {
|
||||
switch(expr[y]) {
|
||||
case '$':
|
||||
if( (str[x]) )
|
||||
ret = NOMATCH;
|
||||
else
|
||||
--x; /* we don't want loop to increment x */
|
||||
break;
|
||||
case '*':
|
||||
while(expr[++y] == '*'){}
|
||||
if(!expr[y])
|
||||
return MATCH;
|
||||
while(str[x]) {
|
||||
switch(_shexp_match(&str[x++],&expr[y], case_insensitive)) {
|
||||
case NOMATCH:
|
||||
continue;
|
||||
case ABORTED:
|
||||
ret = ABORTED;
|
||||
break;
|
||||
default:
|
||||
return MATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if((expr[y] == '$') && (expr[y+1] == '\0') && (!str[x]))
|
||||
return MATCH;
|
||||
else
|
||||
ret = ABORTED;
|
||||
break;
|
||||
case '[':
|
||||
neg = ((expr[++y] == '^') && (expr[y+1] != ']'));
|
||||
if (neg)
|
||||
++y;
|
||||
|
||||
if ((isalnum(expr[y])) && (expr[y+1] == '-') &&
|
||||
(isalnum(expr[y+2])) && (expr[y+3] == ']'))
|
||||
{
|
||||
int start = expr[y], end = expr[y+2];
|
||||
|
||||
/* Droolproofing for pinheads not included */
|
||||
if(neg ^ ((str[x] < start) || (str[x] > end))) {
|
||||
ret = NOMATCH;
|
||||
break;
|
||||
}
|
||||
y+=3;
|
||||
}
|
||||
else {
|
||||
int matched;
|
||||
|
||||
for (matched=0;expr[y] != ']';y++)
|
||||
matched |= (str[x] == expr[y]);
|
||||
if (neg ^ (!matched))
|
||||
ret = NOMATCH;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
return _handle_union(&str[x],&expr[y], case_insensitive);
|
||||
break;
|
||||
case '?':
|
||||
break;
|
||||
case '\\':
|
||||
++y;
|
||||
default:
|
||||
if(case_insensitive)
|
||||
{
|
||||
if(toupper(str[x]) != toupper(expr[y]))
|
||||
ret = NOMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(str[x] != expr[y])
|
||||
ret = NOMATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret)
|
||||
break;
|
||||
}
|
||||
return (ret ? ret : (str[x] ? NOMATCH : MATCH));
|
||||
}
|
||||
|
||||
int
|
||||
NS_WildCardMatch(const PRUnichar *str, const PRUnichar *xp,
|
||||
PRBool case_insensitive) {
|
||||
register int x;
|
||||
PRUnichar *expr = nsCRT::strdup(xp);
|
||||
|
||||
if(!expr)
|
||||
return 1;
|
||||
|
||||
for(x=nsCRT::strlen(expr)-1;x;--x) {
|
||||
if((expr[x] == '~') && (expr[x-1] != '\\')) {
|
||||
expr[x] = '\0';
|
||||
if(_shexp_match(str,&expr[++x], case_insensitive) == MATCH)
|
||||
goto punt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(_shexp_match(str,expr, PR_FALSE) == MATCH) {
|
||||
PR_Free(expr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
punt:
|
||||
PR_Free(expr);
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* shexp.h: Defines and prototypes for shell exp. match routines
|
||||
*
|
||||
*
|
||||
* This routine will match a string with a shell expression. The expressions
|
||||
* accepted are based loosely on the expressions accepted by zsh.
|
||||
*
|
||||
* o * matches anything
|
||||
* o ? matches one character
|
||||
* o \ will escape a special character
|
||||
* o $ matches the end of the string
|
||||
* o [abc] matches one occurence of a, b, or c. The only character that needs
|
||||
* to be escaped in this is ], all others are not special.
|
||||
* o [a-z] matches any character between a and z
|
||||
* o [^az] matches any character except a or z
|
||||
* o ~ followed by another shell expression will remove any pattern
|
||||
* matching the shell expression from the match list
|
||||
* o (foo|bar) will match either the substring foo, or the substring bar.
|
||||
* These can be shell expressions as well.
|
||||
*
|
||||
* The public interface to these routines is documented below.
|
||||
*
|
||||
* Rob McCool
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsWildCard_h__
|
||||
#define nsWildCard_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include <ctype.h> /* isalnum */
|
||||
#include <string.h> /* strlen */
|
||||
|
||||
/* --------------------------- Public routines ---------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* NS_WildCardValid takes a shell expression exp as input. It returns:
|
||||
*
|
||||
* NON_SXP if exp is a standard string
|
||||
* INVALID_SXP if exp is a shell expression, but invalid
|
||||
* VALID_SXP if exp is a valid shell expression
|
||||
*/
|
||||
|
||||
#define NON_SXP -1
|
||||
#define INVALID_SXP -2
|
||||
#define VALID_SXP 1
|
||||
|
||||
extern int NS_WildCardValid(PRUnichar *expr);
|
||||
|
||||
|
||||
/* return values for the search routines */
|
||||
#define MATCH 0
|
||||
#define NOMATCH 1
|
||||
#define ABORTED -1
|
||||
|
||||
/*
|
||||
* NS_WildCardMatch
|
||||
*
|
||||
* Takes a prevalidated shell expression exp, and a string str.
|
||||
*
|
||||
* Returns 0 on match and 1 on non-match.
|
||||
*/
|
||||
|
||||
extern int NS_WildCardMatch(const PRUnichar *str, const PRUnichar *expr,
|
||||
PRBool case_insensitive);
|
||||
|
||||
/*
|
||||
* Same as above, but validates the exp first. 0 on match, 1 on non-match,
|
||||
* -1 on invalid exp.
|
||||
*/
|
||||
|
||||
extern int NS_WildCardSearch(const PRUnichar *str, const PRUnichar *expr);
|
||||
|
||||
/*
|
||||
* Same as above but uses case insensitive search.
|
||||
*/
|
||||
extern int NS_WildCardCaseSearch(const PRUnichar *str, const PRUnichar *expr);
|
||||
|
||||
#endif /* nsWildCard_h__ */
|
Загрузка…
Ссылка в новой задаче