Merge branch 'DRTVWR-591-maint-X' of H:/ViewerDev/viewer-591

# Conflicts:
#	indra/newview/llinventorybridge.cpp
#	indra/newview/llinventorybridge.h
#	indra/newview/llviewerparceloverlay.cpp
#	indra/newview/llviewerparceloverlay.h
master
Ansariel 2023-11-30 19:31:04 +01:00
commit c58a1544bc
11 changed files with 544 additions and 480 deletions

View File

@ -42,16 +42,6 @@ const S32 GESTURE_VERSION = 2;
// LLMultiGesture
//---------------------------------------------------------------------------
LLMultiGesture::LLMultiGesture()
: mKey(),
mMask(),
mName(),
mTrigger(),
mReplaceText(),
mSteps(),
mPlaying(FALSE),
mCurrentStep(0),
mDoneCallback(NULL),
mCallbackData(NULL)
{
reset();
}
@ -67,10 +57,11 @@ void LLMultiGesture::reset()
mPlaying = FALSE;
mCurrentStep = 0;
mWaitTimer.reset();
mWaitingAnimations = FALSE;
mWaitingKeyRelease = FALSE;
mWaitingTimer = FALSE;
mTriggeredByKey = FALSE;
mKeyReleased = FALSE;
mWaitingAnimations = FALSE;
mWaitingAtEnd = FALSE;
mRequestedAnimIDs.clear();
mPlayingAnimIDs.clear();

View File

@ -59,11 +59,11 @@ protected:
const LLMultiGesture& operator=(const LLMultiGesture& rhs);
public:
KEY mKey;
MASK mMask;
KEY mKey { 0 };
MASK mMask { 0 };
// This name can be empty if the inventory item is not around and
// the gesture manager has not yet set the name
// the gesture manager has not yet set the name
std::string mName;
// String, like "/foo" or "hello" that makes it play
@ -75,34 +75,34 @@ public:
std::vector<LLGestureStep*> mSteps;
// Is the gesture currently playing?
BOOL mPlaying;
BOOL mPlaying { FALSE };
// "instruction pointer" for steps
S32 mCurrentStep;
S32 mCurrentStep { 0 };
// We're waiting for triggered animations to stop playing
BOOL mWaitingAnimations;
BOOL mWaitingAnimations { FALSE };
// We're waiting for key release
BOOL mWaitingKeyRelease;
BOOL mWaitingKeyRelease { FALSE };
// We're waiting a fixed amount of time
BOOL mWaitingTimer;
BOOL mWaitingTimer { FALSE };
// We're waiting for triggered animations to stop playing
BOOL mTriggeredByKey;
BOOL mTriggeredByKey { FALSE };
// Has the key been released?
BOOL mKeyReleased;
BOOL mKeyReleased { FALSE };
// Waiting after the last step played for all animations to complete
BOOL mWaitingAtEnd;
BOOL mWaitingAtEnd { FALSE };
// Timer for waiting
LLFrameTimer mWaitTimer;
void (*mDoneCallback)(LLMultiGesture* gesture, void* data);
void* mCallbackData;
void (*mDoneCallback)(LLMultiGesture* gesture, void* data) { NULL };
void* mCallbackData { NULL };
// Animations that we requested to start
std::set<LLUUID> mRequestedAnimIDs;

View File

@ -960,7 +960,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
{
LL_INFOS("GestureMgr") << "Waited too long for key release, continuing gesture."
<< LL_ENDL;
gesture->mWaitingAnimations = FALSE;
gesture->mWaitingKeyRelease = FALSE;
gesture->mCurrentStep++;
}
else
@ -1099,14 +1099,13 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
{
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
if (gesture->mTriggeredByKey // Only wait here IF we were triggered by a key!
&& gesture->mKeyReleased == FALSE // We can only do this once! Prevent gestures infinitely running
&& gesture->mWaitingKeyRelease == FALSE // We can only do this once! Prevent gestures infinitely running
&& wait_step->mFlags & WAIT_FLAG_KEY_RELEASE)
{
// Lets wait for the key release first so we don't hold up re-presses
gesture->mWaitingKeyRelease = TRUE;
// Use the wait timer as a deadlock breaker for key release
// waits.
gesture->mKeyReleased = FALSE;
// Use the wait timer as a deadlock breaker for key release waits.
gesture->mWaitTimer.reset();
}
else if (wait_step->mFlags & WAIT_FLAG_TIME)
@ -1117,8 +1116,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
else if (wait_step->mFlags & WAIT_FLAG_ALL_ANIM)
{
gesture->mWaitingAnimations = TRUE;
// Use the wait timer as a deadlock breaker for animation
// waits.
// Use the wait timer as a deadlock breaker for animation waits.
gesture->mWaitTimer.reset();
}
else

View File

@ -817,9 +817,6 @@ void hide_context_entries(LLMenuGL& menu,
bool found = false;
std::string myinput;
std::vector<std::string> mylist{ "a", "b", "c" };
menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name);
if (itor2 != entries_to_show.end())
{
@ -919,7 +916,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
items.push_back(std::string("Cut"));
if (!isItemMovable() || !isItemRemovable())
if (!isItemMovable() || !canMenuCut())
{
disabled_items.push_back(std::string("Cut"));
}
@ -971,7 +968,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if(!single_folder_root)
{
items.push_back(std::string("Cut"));
if (!isItemMovable() || !isItemRemovable())
if (!isItemMovable() || !canMenuCut())
{
disabled_items.push_back(std::string("Cut"));
}
@ -1146,7 +1143,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
items.push_back(std::string("Delete"));
if (!isItemRemovable(false) || isPanelActive("Favorite Items"))
if (isPanelActive("Favorite Items") || !canMenuDelete())
{
disabled_items.push_back(std::string("Delete"));
}
@ -1302,6 +1299,16 @@ void LLInvFVBridge::addLinkReplaceMenuOption(menuentry_vec_t& items, menuentry_v
}
}
bool LLInvFVBridge::canMenuDelete()
{
return isItemRemovable(false);
}
bool LLInvFVBridge::canMenuCut()
{
return isItemRemovable(true);
}
// <FS:Ansariel> Move to default folder
void LLInvFVBridge::addMoveToDefaultFolderMenuOption(menuentry_vec_t& items)
{
@ -4968,7 +4975,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
return;
}
if (!isItemRemovable(false))
if (!canMenuDelete())
{
disabled_items.push_back(std::string("Delete"));
}
@ -5371,6 +5378,192 @@ void LLFolderBridge::modifyOutfit(BOOL append)
}
}
//static
void LLFolderBridge::onCanDeleteIdle(void* user_data)
{
LLFolderBridge* self = (LLFolderBridge*)user_data;
// we really need proper onidle mechanics that returns available time
const F32 EXPIRY_SECONDS = 0.008f;
LLTimer timer;
timer.setTimerExpirySec(EXPIRY_SECONDS);
LLInventoryModel* model = self->getInventoryModel();
if (model)
{
switch (self->mCanDeleteFolderState)
{
case CDS_INIT_FOLDER_CHECK:
// Can still be expensive, split it further?
model->collectDescendents(
self->mUUID,
self->mFoldersToCheck,
self->mItemsToCheck,
LLInventoryModel::EXCLUDE_TRASH);
self->mCanDeleteFolderState = CDS_PROCESSING_ITEMS;
break;
case CDS_PROCESSING_ITEMS:
while (!timer.hasExpired() && !self->mItemsToCheck.empty())
{
LLViewerInventoryItem* item = self->mItemsToCheck.back().get();
if (item)
{
if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item))
{
if (get_is_item_worn(item))
{
// At the moment we disable 'cut' if category has worn items (do we need to?)
// but allow 'delete' to happen since it will prompt user to detach
self->mCanCut = false;
}
}
if (!item->getIsLinkType() && get_is_item_worn(item))
{
self->mCanCut = false;
}
}
self->mItemsToCheck.pop_back();
}
self->mCanDeleteFolderState = CDS_PROCESSING_FOLDERS;
break;
case CDS_PROCESSING_FOLDERS:
{
const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
LLViewerInventoryCategory* outfit_linked_category = base_outfit_link ? base_outfit_link->getLinkedCategory() : nullptr;
while (!timer.hasExpired() && !self->mFoldersToCheck.empty())
{
LLViewerInventoryCategory* cat = self->mFoldersToCheck.back().get();
if (cat)
{
const LLFolderType::EType folder_type = cat->getPreferredType();
if (LLFolderType::lookupIsProtectedType(folder_type))
{
self->mCanCut = false;
self->mCanDelete = false;
self->completeDeleteProcessing();
break;
}
// Can't delete the outfit that is currently being worn.
if (folder_type == LLFolderType::FT_OUTFIT)
{
if (cat == outfit_linked_category)
{
self->mCanCut = false;
self->mCanDelete = false;
self->completeDeleteProcessing();
break;
}
}
}
self->mFoldersToCheck.pop_back();
}
}
self->mCanDeleteFolderState = CDS_DONE;
break;
case CDS_DONE:
self->completeDeleteProcessing();
break;
}
}
}
bool LLFolderBridge::canMenuDelete()
{
LLInventoryModel* model = getInventoryModel();
if (!model) return false;
LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
if (!category)
{
return false;
}
S32 version = category->getVersion();
if (mLastCheckedVersion == version)
{
return mCanDelete;
}
initCanDeleteProcessing(model, version);
return false;
}
bool LLFolderBridge::canMenuCut()
{
LLInventoryModel* model = getInventoryModel();
if (!model) return false;
LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
if (!category)
{
return false;
}
S32 version = category->getVersion();
if (mLastCheckedVersion == version)
{
return mCanCut;
}
initCanDeleteProcessing(model, version);
return false;
}
void LLFolderBridge::initCanDeleteProcessing(LLInventoryModel* model, S32 version)
{
if (mCanDeleteFolderState == CDS_DONE
|| mInProgressVersion != version)
{
if (get_is_category_removable(model, mUUID))
{
// init recursive check of content
mInProgressVersion = version;
mCanCut = true;
mCanDelete = true;
mCanDeleteFolderState = CDS_INIT_FOLDER_CHECK;
mFoldersToCheck.clear();
mItemsToCheck.clear();
gIdleCallbacks.addFunction(onCanDeleteIdle, this);
}
else
{
// no check needed
mCanDelete = false;
mCanCut = false;
mLastCheckedVersion = version;
mCanDeleteFolderState = CDS_DONE;
mFoldersToCheck.clear();
mItemsToCheck.clear();
}
}
}
void LLFolderBridge::completeDeleteProcessing()
{
LLInventoryModel* model = getInventoryModel();
LLViewerInventoryCategory* category = model ? (LLViewerInventoryCategory*)model->getCategory(mUUID) : nullptr;
if (model && category && category->getVersion() == mInProgressVersion)
{
mLastCheckedVersion = mInProgressVersion;
mCanDeleteFolderState = CDS_DONE;
gIdleCallbacks.deleteFunction(onCanDeleteIdle, this);
}
else
{
mCanDelete = false;
mCanCut = false;
mLastCheckedVersion = LLViewerInventoryCategory::VERSION_UNKNOWN;
mCanDeleteFolderState = CDS_DONE;
}
if (mRoot)
{
mRoot->updateMenu();
}
}
// <FS:Ansariel> FIRE-29342: Protect folder option
bool LLFolderBridge::isProtected() const
{
@ -5545,6 +5738,27 @@ void drop_to_favorites_cb(const LLUUID& id, LLPointer<LLInventoryCallback> cb1,
cb2->fire(id);
}
LLFolderBridge::LLFolderBridge(LLInventoryPanel* inventory,
LLFolderView* root,
const LLUUID& uuid)
: LLInvFVBridge(inventory, root, uuid)
, mCallingCards(FALSE)
, mWearables(FALSE)
, mIsLoading(false)
, mShowDescendantsCount(false)
, mCanDeleteFolderState(CDS_DONE)
, mLastCheckedVersion(S32_MIN)
, mInProgressVersion(S32_MIN)
, mCanDelete(false)
, mCanCut(false)
{
}
LLFolderBridge::~LLFolderBridge()
{
gIdleCallbacks.deleteFunction(onCanDeleteIdle, this);
}
void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb)
{
// use callback to rearrange favorite landmarks after adding

View File

@ -166,6 +166,9 @@ protected:
virtual void addLinkReplaceMenuOption(menuentry_vec_t& items,
menuentry_vec_t& disabled_items);
virtual bool canMenuDelete();
virtual bool canMenuCut();
// <FS:Ansariel> Move to default folder
virtual void addMoveToDefaultFolderMenuOption(menuentry_vec_t& items);
@ -290,14 +293,10 @@ class LLFolderBridge : public LLInvFVBridge
public:
LLFolderBridge(LLInventoryPanel* inventory,
LLFolderView* root,
const LLUUID& uuid)
: LLInvFVBridge(inventory, root, uuid),
mCallingCards(FALSE),
mWearables(FALSE),
mIsLoading(false),
mShowDescendantsCount(false)
{}
const LLUUID& uuid);
~LLFolderBridge();
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL);
void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item);
@ -419,6 +418,31 @@ protected:
LLTimer mTimeSinceRequestStart;
std::string mMessage;
LLRootHandle<LLFolderBridge> mHandle;
private:
// checking if folder is cutable or deletable is expensive,
// cache values and split check over frames
static void onCanDeleteIdle(void* user_data);
void initCanDeleteProcessing(LLInventoryModel* model, S32 version);
void completeDeleteProcessing();
bool canMenuDelete();
bool canMenuCut();
enum ECanDeleteState
{
CDS_INIT_FOLDER_CHECK,
CDS_PROCESSING_ITEMS,
CDS_PROCESSING_FOLDERS,
CDS_DONE,
};
ECanDeleteState mCanDeleteFolderState;
LLInventoryModel::cat_array_t mFoldersToCheck;
LLInventoryModel::item_array_t mItemsToCheck;
S32 mLastCheckedVersion;
S32 mInProgressVersion;
bool mCanDelete;
bool mCanCut;
};
class LLTextureBridge : public LLItemBridge

View File

@ -917,25 +917,27 @@ bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUI
item_array,
LLInventoryModel::EXCLUDE_TRASH);
for (LLInventoryModel::item_array_t::value_type& item : item_array)
if (check_worn)
{
// Disable delete from COF folder; have users explicitly choose "detach/take off",
// unless the item is not worn but in the COF (i.e. is bugged).
if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item))
for (LLInventoryModel::item_array_t::value_type& item : item_array)
{
if (get_is_item_worn(item))
// Disable delete/cut from COF folder; have users explicitly choose "detach/take off",
// unless the item is not worn but in the COF (i.e. is bugged).
if (item)
{
return false;
}
}
if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item))
{
if (get_is_item_worn(item))
{
return false;
}
}
if (item && item->getIsLinkType())
{
return true;
}
if (check_worn && get_is_item_worn(item))
{
return false;
if (!item->getIsLinkType() && get_is_item_worn(item))
{
return false;
}
}
}
}

View File

@ -50,7 +50,10 @@
#include "pipeline.h"
const U8 OVERLAY_IMG_COMPONENTS = 4;
static const U8 OVERLAY_IMG_COMPONENTS = 4;
static const S32 FLOATS_PER_VERTEX = LENGTHOFVECTOR3;
static const S32 BYTES_PER_COLOR = LENGTHOFCOLOR4U;
static const F32 LINE_WIDTH = 0.0625f;
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3)
LLViewerParcelOverlay::update_signal_t* LLViewerParcelOverlay::mUpdateSignal = NULL;
@ -64,11 +67,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_
// </FS:CR> Aurora Sim
mDirty( FALSE ),
mTimeSinceLastUpdate(),
mOverlayTextureIdx(-1),
mVertexCount(0),
mVertexArray(NULL),
mColorArray(NULL)
// mTexCoordArray(NULL),
mOverlayTextureIdx(-1)
{
// Create a texture to hold color information.
// 4 components
@ -106,17 +105,6 @@ LLViewerParcelOverlay::~LLViewerParcelOverlay()
{
delete[] mOwnership;
mOwnership = NULL;
delete[] mVertexArray;
mVertexArray = NULL;
delete[] mColorArray;
mColorArray = NULL;
// JC No textures.
// delete mTexCoordArray;
// mTexCoordArray = NULL;
mImageRaw = NULL;
}
@ -319,7 +307,6 @@ F32 LLViewerParcelOverlay::getOwnedRatio() const
}
return (F32)total / (F32)size;
}
//---------------------------------------------------------------------------
@ -336,14 +323,13 @@ F32 LLViewerParcelOverlay::getOwnedRatio() const
// Note: Assumes that the ownership array and
void LLViewerParcelOverlay::updateOverlayTexture()
{
if (mOverlayTextureIdx < 0 && mDirty)
{
mOverlayTextureIdx = 0;
}
if (mOverlayTextureIdx < 0)
{
return;
if (!mDirty)
return;
mOverlayTextureIdx = 0;
}
const LLColor4U avail = LLUIColorTable::instance().getColor("PropertyColorAvail").get();
const LLColor4U owned = LLUIColorTable::instance().getColor("PropertyColorOther").get();
const LLColor4U group = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
@ -453,42 +439,44 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay)
setDirty();
}
void LLViewerParcelOverlay::updatePropertyLines()
{
// <FS:Ansariel> Use faster LLCachedControls for frequently visited locations
//if (!gSavedSettings.getBOOL("ShowPropertyLines"))
static LLCachedControl<bool> showPropertyLines(gSavedSettings, "ShowPropertyLines");
if (!showPropertyLines)
// </FS:Ansariel>
static LLCachedControl<bool> show(gSavedSettings, "ShowPropertyLines");
if (!show)
return;
S32 row, col;
const LLColor4U self_coloru = LLUIColorTable::instance().getColor("PropertyColorSelf").get();
const LLColor4U other_coloru = LLUIColorTable::instance().getColor("PropertyColorOther").get();
const LLColor4U group_coloru = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
const LLColor4U for_sale_coloru = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
const LLColor4U auction_coloru = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
LLColor4U colors[PARCEL_COLOR_MASK + 1];
colors[PARCEL_SELF] = LLUIColorTable::instance().getColor("PropertyColorSelf").get();
colors[PARCEL_OWNED] = LLUIColorTable::instance().getColor("PropertyColorOther").get();
colors[PARCEL_GROUP] = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
colors[PARCEL_FOR_SALE] = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
colors[PARCEL_AUCTION] = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
// Build into dynamic arrays, then copy into static arrays.
std::vector<LLVector3> new_vertex_array;
new_vertex_array.reserve(256);
std::vector<LLColor4U> new_color_array;
new_color_array.reserve(256);
std::vector<LLVector2> new_coord_array;
new_coord_array.reserve(256);
mEdges.clear();
U8 overlay = 0;
BOOL add_edge = FALSE;
const F32 GRID_STEP = PARCEL_GRID_STEP_METERS;
const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
for (row = 0; row < GRIDS_PER_EDGE; row++)
for (S32 row = 0; row < GRIDS_PER_EDGE; row++)
{
for (col = 0; col < GRIDS_PER_EDGE; col++)
for (S32 col = 0; col < GRIDS_PER_EDGE; col++)
{
overlay = mOwnership[row*GRIDS_PER_EDGE+col];
U8 overlay = mOwnership[row*GRIDS_PER_EDGE+col];
S32 colorIndex = overlay & PARCEL_COLOR_MASK;
switch(colorIndex)
{
case PARCEL_SELF:
case PARCEL_GROUP:
case PARCEL_OWNED:
case PARCEL_FOR_SALE:
case PARCEL_AUCTION:
break;
default:
continue;
}
const LLColor4U& color = colors[colorIndex];
F32 left = col*GRID_STEP;
F32 right = left+GRID_STEP;
@ -499,259 +487,41 @@ void LLViewerParcelOverlay::updatePropertyLines()
// West edge
if (overlay & PARCEL_WEST_LINE)
{
switch(overlay & PARCEL_COLOR_MASK)
{
case PARCEL_SELF:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, WEST, self_coloru);
break;
case PARCEL_GROUP:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, WEST, group_coloru);
break;
case PARCEL_OWNED:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, WEST, other_coloru);
break;
case PARCEL_FOR_SALE:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, WEST, for_sale_coloru);
break;
case PARCEL_AUCTION:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, WEST, auction_coloru);
break;
default:
break;
}
addPropertyLine(left, bottom, 0, 1, LINE_WIDTH, 0, color);
}
// East edge
if (col < GRIDS_PER_EDGE-1)
if (col == GRIDS_PER_EDGE - 1 || mOwnership[row * GRIDS_PER_EDGE + col + 1] & PARCEL_WEST_LINE)
{
U8 east_overlay = mOwnership[row*GRIDS_PER_EDGE+col+1];
add_edge = east_overlay & PARCEL_WEST_LINE;
}
else
{
add_edge = TRUE;
}
if (add_edge)
{
switch(overlay & PARCEL_COLOR_MASK)
{
case PARCEL_SELF:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
right, bottom, EAST, self_coloru);
break;
case PARCEL_GROUP:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
right, bottom, EAST, group_coloru);
break;
case PARCEL_OWNED:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
right, bottom, EAST, other_coloru);
break;
case PARCEL_FOR_SALE:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
right, bottom, EAST, for_sale_coloru);
break;
case PARCEL_AUCTION:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
right, bottom, EAST, auction_coloru);
break;
default:
break;
}
addPropertyLine(right, bottom, 0, 1, -LINE_WIDTH, 0, color);
}
// South edge
if (overlay & PARCEL_SOUTH_LINE)
{
switch(overlay & PARCEL_COLOR_MASK)
{
case PARCEL_SELF:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, SOUTH, self_coloru);
break;
case PARCEL_GROUP:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, SOUTH, group_coloru);
break;
case PARCEL_OWNED:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, SOUTH, other_coloru);
break;
case PARCEL_FOR_SALE:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, SOUTH, for_sale_coloru);
break;
case PARCEL_AUCTION:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, bottom, SOUTH, auction_coloru);
break;
default:
break;
}
addPropertyLine(left, bottom, 1, 0, 0, LINE_WIDTH, color);
}
// North edge
if (row < GRIDS_PER_EDGE-1)
if (row == GRIDS_PER_EDGE - 1 || mOwnership[(row + 1) * GRIDS_PER_EDGE + col] & PARCEL_SOUTH_LINE)
{
U8 north_overlay = mOwnership[(row+1)*GRIDS_PER_EDGE+col];
add_edge = north_overlay & PARCEL_SOUTH_LINE;
}
else
{
add_edge = TRUE;
}
if (add_edge)
{
switch(overlay & PARCEL_COLOR_MASK)
{
case PARCEL_SELF:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, top, NORTH, self_coloru);
break;
case PARCEL_GROUP:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, top, NORTH, group_coloru);
break;
case PARCEL_OWNED:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, top, NORTH, other_coloru);
break;
case PARCEL_FOR_SALE:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, top, NORTH, for_sale_coloru);
break;
case PARCEL_AUCTION:
addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
left, top, NORTH, auction_coloru);
break;
default:
break;
}
addPropertyLine(left, top, 1, 0, 0, -LINE_WIDTH, color);
}
}
}
// Now copy into static arrays for faster rendering.
// Attempt to recycle old arrays if possible to avoid memory
// shuffling.
S32 new_vertex_count = new_vertex_array.size();
if (!(mVertexArray && mColorArray && new_vertex_count == mVertexCount))
{
// ...need new arrays
delete[] mVertexArray;
mVertexArray = NULL;
delete[] mColorArray;
mColorArray = NULL;
mVertexCount = new_vertex_count;
if (new_vertex_count > 0)
{
mVertexArray = new F32[3 * mVertexCount];
mColorArray = new U8 [4 * mVertexCount];
}
}
// Copy the new data into the arrays
S32 i;
F32* vertex = mVertexArray;
for (i = 0; i < mVertexCount; i++)
{
const LLVector3& point = new_vertex_array.at(i);
*vertex = point.mV[VX];
vertex++;
*vertex = point.mV[VY];
vertex++;
*vertex = point.mV[VZ];
vertex++;
}
U8* colorp = mColorArray;
for (i = 0; i < mVertexCount; i++)
{
const LLColor4U& color = new_color_array.at(i);
*colorp = color.mV[VRED];
colorp++;
*colorp = color.mV[VGREEN];
colorp++;
*colorp = color.mV[VBLUE];
colorp++;
*colorp = color.mV[VALPHA];
colorp++;
}
// Everything's clean now
mDirty = FALSE;
}
void LLViewerParcelOverlay::addPropertyLine(
std::vector<LLVector3>& vertex_array,
std::vector<LLColor4U>& color_array,
std::vector<LLVector2>& coord_array,
const F32 start_x, const F32 start_y,
const U32 edge,
const LLColor4U& color)
void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F32 dy, F32 tick_dx, F32 tick_dy, const LLColor4U& color)
{
LLColor4U underwater( color );
underwater.mV[VALPHA] /= 2;
vertex_array.reserve(16);
color_array.reserve(16);
coord_array.reserve(16);
LLSurface& land = mRegion->getLand();
F32 water_z = land.getWaterHeight();
F32 dx;
F32 dy;
F32 tick_dx;
F32 tick_dy;
//const F32 LINE_WIDTH = 0.125f;
const F32 LINE_WIDTH = 0.0625f;
switch(edge)
{
case WEST:
dx = 0.f;
dy = 1.f;
tick_dx = LINE_WIDTH;
tick_dy = 0.f;
break;
case EAST:
dx = 0.f;
dy = 1.f;
tick_dx = -LINE_WIDTH;
tick_dy = 0.f;
break;
case NORTH:
dx = 1.f;
dy = 0.f;
tick_dx = 0.f;
tick_dy = -LINE_WIDTH;
break;
case SOUTH:
dx = 1.f;
dy = 0.f;
tick_dx = 0.f;
tick_dy = LINE_WIDTH;
break;
default:
LL_ERRS() << "Invalid edge in addPropertyLine" << LL_ENDL;
return;
}
mEdges.resize(mEdges.size() + 1);
Edge& edge = mEdges.back();
edge.color = color;
F32 outside_x = start_x;
F32 outside_y = start_y;
@ -760,14 +530,31 @@ void LLViewerParcelOverlay::addPropertyLine(
F32 inside_y = start_y + tick_dy;
F32 inside_z = 0.f;
auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part)
{
F32 new_x = start.mV[0] + (x - start.mV[0]) * part;
F32 new_y = start.mV[1] + (y - start.mV[1]) * part;
F32 new_z = start.mV[2] + (z - start.mV[2]) * part;
edge.vertices.emplace_back(new_x, new_y, new_z);
};
auto checkForSplit = [&]()
{
const LLVector3& last_outside = edge.vertices.back();
F32 z0 = last_outside.mV[2];
F32 z1 = outside_z;
if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z))
return;
F32 part = (water_z - z0) / (z1 - z0);
const LLVector3& last_inside = edge.vertices[edge.vertices.size() - 2];
split(last_inside, inside_x, inside_y, inside_z, part);
split(last_outside, outside_x, outside_y, outside_z, part);
};
// First part, only one vertex
outside_z = land.resolveHeightRegion( outside_x, outside_y );
if (outside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
edge.vertices.emplace_back(outside_x, outside_y, outside_z);
inside_x += dx * LINE_WIDTH;
inside_y += dy * LINE_WIDTH;
@ -779,17 +566,8 @@ void LLViewerParcelOverlay::addPropertyLine(
inside_z = land.resolveHeightRegion( inside_x, inside_y );
outside_z = land.resolveHeightRegion( outside_x, outside_y );
if (inside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
if (outside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) );
vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
coord_array.push_back( LLVector2(outside_x - start_x, 1.f) );
coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
edge.vertices.emplace_back(inside_x, inside_y, inside_z);
edge.vertices.emplace_back(outside_x, outside_y, outside_z);
inside_x += dx * (dx - LINE_WIDTH);
inside_y += dy * (dy - LINE_WIDTH);
@ -798,24 +576,16 @@ void LLViewerParcelOverlay::addPropertyLine(
outside_y += dy * (dy - LINE_WIDTH);
// Middle part, full width
S32 i;
const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS );
for (i = 1; i < GRID_STEP; i++)
for (S32 i = 1; i < GRID_STEP; i++)
{
inside_z = land.resolveHeightRegion( inside_x, inside_y );
outside_z = land.resolveHeightRegion( outside_x, outside_y );
if (inside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
checkForSplit();
if (outside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) );
vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
coord_array.push_back( LLVector2(outside_x - start_x, 1.f) );
coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
edge.vertices.emplace_back(inside_x, inside_y, inside_z);
edge.vertices.emplace_back(outside_x, outside_y, outside_z);
inside_x += dx;
inside_y += dy;
@ -834,20 +604,10 @@ void LLViewerParcelOverlay::addPropertyLine(
inside_z = land.resolveHeightRegion( inside_x, inside_y );
outside_z = land.resolveHeightRegion( outside_x, outside_y );
if (inside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
checkForSplit();
if (outside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) );
vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
coord_array.push_back( LLVector2(outside_x - start_x, 1.f) );
coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
inside_x += dx * LINE_WIDTH;
inside_y += dy * LINE_WIDTH;
edge.vertices.emplace_back(inside_x, inside_y, inside_z);
edge.vertices.emplace_back(outside_x, outside_y, outside_z);
outside_x += dx * LINE_WIDTH;
outside_y += dy * LINE_WIDTH;
@ -855,14 +615,9 @@ void LLViewerParcelOverlay::addPropertyLine(
// Last edge is not drawn to the edge
outside_z = land.resolveHeightRegion( outside_x, outside_y );
if (outside_z > 20.f) color_array.push_back( color );
else color_array.push_back( underwater );
vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
edge.vertices.emplace_back(outside_x, outside_y, outside_z);
}
void LLViewerParcelOverlay::setDirty()
{
mDirty = TRUE;
@ -902,22 +657,15 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update)
}
}
S32 LLViewerParcelOverlay::renderPropertyLines ()
void LLViewerParcelOverlay::renderPropertyLines()
{
// <FS:Ansariel> Use faster LLCachedControls for frequently visited locations
//if (!gSavedSettings.getBOOL("ShowPropertyLines"))
static LLCachedControl<bool> showPropertyLines(gSavedSettings, "ShowPropertyLines");
if (!showPropertyLines)
// </FS:Ansariel>
{
return 0;
}
if (!mVertexArray || !mColorArray)
{
return 0;
}
static LLCachedControl<bool> show(gSavedSettings, "ShowPropertyLines");
if (!show)
return;
LLSurface& land = mRegion->getLand();
F32 water_z = land.getWaterHeight() + 0.01f;
LLGLSUIDefault gls_ui; // called from pipeline
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@ -944,16 +692,11 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
gGL.translatef( origin.mV[VX], origin.mV[VY], origin.mV[VZ] );
gGL.translatef(origin.mV[VX], origin.mV[VY], origin.mV[VZ]);
gGL.translatef(pull_toward_camera.mV[VX], pull_toward_camera.mV[VY],
pull_toward_camera.mV[VZ]);
// Include +1 because vertices are fenceposts.
// *2 because it's a quad strip
const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS );
const S32 vertex_per_edge = 3 + 2 * (GRID_STEP-1) + 3;
// Stomp the camera into two dimensions
LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() );
@ -963,91 +706,68 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS;
cull_plane_point += camera_region;
LLVector3 vertex;
const S32 BYTES_PER_COLOR = 4;
const S32 FLOATS_PER_VERTEX = 3;
//const S32 FLOATS_PER_TEX_COORD = 2;
S32 i, j;
S32 drawn = 0;
F32* vertexp;
U8* colorp;
bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build");
const F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f;
for (i = 0; i < mVertexCount; i += vertex_per_edge)
for (const Edge& edge : mEdges)
{
colorp = mColorArray + BYTES_PER_COLOR * i;
vertexp = mVertexArray + FLOATS_PER_VERTEX * i;
LLVector3 center = edge.vertices[edge.vertices.size() >> 1];
vertex.mV[VX] = *(vertexp);
vertex.mV[VY] = *(vertexp+1);
vertex.mV[VZ] = *(vertexp+2);
if (dist_vec_squared2D(vertex, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
if (dist_vec_squared2D(center, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
{
continue;
}
// Destroy vertex, transform to plane-local.
vertex -= cull_plane_point;
center -= cull_plane_point;
// negative dot product means it is in back of the plane
if ( vertex * CAMERA_AT < 0.f )
// Negative dot product means it is in back of the plane
if (center * CAMERA_AT < 0.f)
{
continue;
}
gGL.begin(LLRender::TRIANGLE_STRIP);
for (j = 0; j < vertex_per_edge; j++)
{
gGL.color4ubv(colorp);
gGL.vertex3fv(vertexp);
gGL.color4ubv(edge.color.mV);
colorp += BYTES_PER_COLOR;
vertexp += FLOATS_PER_VERTEX;
for (const LLVector3& vertex : edge.vertices)
{
if (render_hidden || camera_z < water_z || vertex.mV[2] >= water_z)
{
gGL.vertex3fv(vertex.mV);
}
else
{
LLVector3 visible = vertex;
visible.mV[2] = water_z;
gGL.vertex3fv(visible.mV);
}
}
drawn += vertex_per_edge;
gGL.end();
if (render_hidden)
{
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
colorp = mColorArray + BYTES_PER_COLOR * i;
vertexp = mVertexArray + FLOATS_PER_VERTEX * i;
gGL.begin(LLRender::TRIANGLE_STRIP);
for (j = 0; j < vertex_per_edge; j++)
LLColor4U color = edge.color;
color.mV[3] /= 4;
gGL.color4ubv(color.mV);
for (const LLVector3& vertex : edge.vertices)
{
U8 color[4];
color[0] = colorp[0];
color[1] = colorp[1];
color[2] = colorp[2];
color[3] = colorp[3]/4;
gGL.color4ubv(color);
gGL.vertex3fv(vertexp);
colorp += BYTES_PER_COLOR;
vertexp += FLOATS_PER_VERTEX;
gGL.vertex3fv(vertex.mV);
}
drawn += vertex_per_edge;
gGL.end();
}
}
gGL.popMatrix();
return drawn;
}
// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
@ -1071,11 +791,9 @@ void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F3
void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
{
if (!mOwnership)
{
return;
}
if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
static LLCachedControl<bool> show(gSavedSettings, "MiniMapShowPropertyLines");
if (!mOwnership || !show)
{
return;
}
@ -1090,11 +808,11 @@ void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_me
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glLineWidth(1.0f);
gGL.color4fv(parcel_outline_color);
for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
for (S32 i = 0; i <= GRIDS_PER_EDGE; i++)
{
const F32 bottom = region_bottom + (i * map_parcel_width);
const F32 top = bottom + map_parcel_width;
for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
for (S32 j = 0; j <= GRIDS_PER_EDGE; j++)
{
const F32 left = region_left + (j * map_parcel_width);
const F32 right = left + map_parcel_width;

View File

@ -71,8 +71,8 @@ public:
// [/SL:KB]
// Returns the number of vertices drawn
S32 renderPropertyLines();
void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
void renderPropertyLines();
void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@ -86,7 +86,7 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3)
typedef boost::signals2::signal<void (const LLViewerRegion*)> update_signal_t;
static boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type & cb);
@ -100,12 +100,7 @@ private:
U8 parcelFlags(S32 row, S32 col, U8 flags) const;
void addPropertyLine(std::vector<LLVector3>& vertex_array,
std::vector<LLColor4U>& color_array,
std::vector<LLVector2>& coord_array,
const F32 start_x, const F32 start_y,
const U32 edge,
const LLColor4U& color);
void addPropertyLine(F32 start_x, F32 start_y, F32 dx, F32 dy, F32 tick_dx, F32 tick_dy, const LLColor4U& color);
void updateOverlayTexture();
void updatePropertyLines();
@ -131,10 +126,14 @@ private:
BOOL mDirty;
LLFrameTimer mTimeSinceLastUpdate;
S32 mOverlayTextureIdx;
S32 mVertexCount;
F32* mVertexArray;
U8* mColorArray;
struct Edge
{
std::vector<LLVector3> vertices;
LLColor4U color;
};
std::vector<Edge> mEdges;
// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3)
static update_signal_t* mUpdateSignal;

View File

@ -1149,15 +1149,11 @@ void LLViewerRegion::setCacheID(const LLUUID& id)
mImpl->mCacheID = id;
}
S32 LLViewerRegion::renderPropertyLines()
void LLViewerRegion::renderPropertyLines()
{
if (mParcelOverlay)
{
return mParcelOverlay->renderPropertyLines();
}
else
{
return 0;
mParcelOverlay->renderPropertyLines();
}
}

View File

@ -166,7 +166,7 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
S32 renderPropertyLines();
void renderPropertyLines();
void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);

View File

@ -0,0 +1,122 @@
#!/usr/bin/env python3
"""\
This script formats XML files in a given directory with options for indentation and space removal.
$LicenseInfo:firstyear=2023&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2023, Linden Research, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License only.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
import os
import sys
import glob
import io
import xml.etree.ElementTree as ET
def get_xml_declaration(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
first_line = file.readline().strip()
if first_line.startswith('<?xml'):
return first_line
return None
def parse_xml_file(file_path):
try:
tree = ET.parse(file_path)
return tree
except ET.ParseError as e:
print(f"Error parsing XML file {file_path}: {e}")
return None
def indent(elem, level=0, indent_text=False, indent_tab=False):
indent_string = "\t" if indent_tab else " "
i = "\n" + level * indent_string
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + indent_string
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level + 1, indent_text, indent_tab)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
if indent_text and elem.text and not elem.text.isspace():
elem.text = "\n" + (level + 1) * indent_string + elem.text.strip() + "\n" + level * indent_string
def save_xml(tree, file_path, xml_decl, indent_text=False, indent_tab=False, rm_space=False, rewrite_decl=False):
if tree is not None:
root = tree.getroot()
indent(root, indent_text=indent_text, indent_tab=indent_tab)
xml_string = ET.tostring(root, encoding='unicode')
if rm_space:
xml_string = xml_string.replace(' />', '/>')
xml_decl = (xml_decl if (xml_decl and not rewrite_decl)
else '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>')
try:
with io.open(file_path, 'wb') as file:
file.write(xml_decl.encode('utf-8'))
file.write('\n'.encode('utf-8'))
file.write(xml_string.encode('utf-8'))
except IOError as e:
print(f"Error saving file {file_path}: {e}")
def process_directory(directory_path, indent_text=False, indent_tab=False, rm_space=False, rewrite_decl=False):
if not os.path.isdir(directory_path):
print(f"Directory not found: {directory_path}")
return
xml_files = glob.glob(os.path.join(directory_path, "*.xml"))
if not xml_files:
print(f"No XML files found in directory: {directory_path}")
return
for file_path in xml_files:
xml_decl = get_xml_declaration(file_path)
tree = parse_xml_file(file_path)
if tree is not None:
save_xml(tree, file_path, xml_decl, indent_text, indent_tab, rm_space, rewrite_decl)
if __name__ == "__main__":
if len(sys.argv) < 2 or '--help' in sys.argv:
print("This script formats XML files in a given directory. Useful to fix XUI XMLs after processing by other tools.")
print("\nUsage:")
print(" python fix_xml_indentations.py <path/to/directory> [options]")
print("\nOptions:")
print(" --indent-text Indents text within XML tags.")
print(" --indent-tab Uses tabs instead of spaces for indentation.")
print(" --rm-space Removes spaces in self-closing tags.")
print(" --rewrite_decl Replaces the XML declaration line.")
print("\nCommon Usage:")
print(" To format XML files with text indentation, tab indentation, and removal of spaces in self-closing tags:")
print(" python fix_xml_indentations.py /path/to/xmls --indent-text --indent-tab --rm-space")
sys.exit(1)
directory_path = sys.argv[1]
indent_text = '--indent-text' in sys.argv
indent_tab = '--indent-tab' in sys.argv
rm_space = '--rm-space' in sys.argv
rewrite_decl = '--rewrite_decl' in sys.argv
process_directory(directory_path, indent_text, indent_tab, rm_space, rewrite_decl)