diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 5d86a6415..6c29e3fd2 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -105,6 +105,7 @@ set(llcommon_HEADER_FILES CMakeLists.txt aiframetimer.h + airecursive.h aithreadid.h aithreadsafe.h bitpack.h diff --git a/indra/llcommon/airecursive.h b/indra/llcommon/airecursive.h new file mode 100644 index 000000000..0b22535a8 --- /dev/null +++ b/indra/llcommon/airecursive.h @@ -0,0 +1,58 @@ +/** + * @file airecursive.h + * @brief Declaration of AIRecursive. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 05/01/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AI_RECURSIVE +#define AI_RECURSIVE + +// Exception safe class to detect recursive calls. +// +// A unique, static bool must be passed (thread local if the function is +// called by more than one thread). +// +// Example usage: +// +// void f() +// { +// static bool recursive; +// if (recursive) return; +// AIRecursive dummy(flag); +// ... +// } + +class AIRecursive { + private: + bool& mFlag; + + public: + AIRecursive(bool& flag) : mFlag(flag) { mFlag = true; } + ~AIRecursive() { mFlag = false; } +}; + +#endif // AI_RECURSIVE diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 25370f739..1cbb52dab 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -57,6 +57,7 @@ #include "lltabcontainer.h" #include "v2math.h" #include "llfasttimer.h" +#include "airecursive.h" const S32 MINIMIZED_WIDTH = 160; const S32 CLOSE_BOX_FROM_TOP = 1; @@ -1988,9 +1989,16 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF return new_rect; } - void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) { + // Stop recursive call sequence + // LLFloaterView::bringToFront calls + // LLFloater::setFocus calls + // LLFloater::setFrontmost calls this again. + static bool recursive; + if (recursive) { return; } + AIRecursive enter(recursive); + // *TODO: make this respect floater's mAutoFocus value, instead of // using parameter if (child->getHost()) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2850f52ee..a93b71a2e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14644,17 +14644,6 @@ This should be as low as possible, but too low may break functionality Value 0 - UseFreezeTime - - Comment - Freeze time when taking snapshots. - Persist - 0 - Type - Boolean - Value - 0 - UseInventoryLinks Comment diff --git a/indra/newview/llfloaterfeed.cpp b/indra/newview/llfloaterfeed.cpp index 7b39b13e3..0fb31467e 100644 --- a/indra/newview/llfloaterfeed.cpp +++ b/indra/newview/llfloaterfeed.cpp @@ -42,6 +42,7 @@ #include "llviewertexture.h" #include "llviewerwindow.h" #include "llwebprofile.h" +#include "lluploaddialog.h" #include @@ -135,8 +136,7 @@ void LLFloaterFeed::draw(void) void LLFloaterFeed::onClickCancel() { - // Return false on cancel, to enable the upload button again. - LLFloaterSnapshot::saveFeedDone(false, mSnapshotIndex); + // Cancel is the same as just closing the floater. close(false); } @@ -152,23 +152,17 @@ void LLFloaterFeed::onClickPost() { static LLCachedControl add_location("SnapshotFeedAddLocation"); const std::string caption = childGetValue("caption").asString(); - LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::saveFeedDone, _1, mPNGImage)); + LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::saveFeedDone, _1, mSnapshotIndex)); + LLFloaterSnapshot::saveStart(mSnapshotIndex); LLWebProfile::uploadImage(mPNGImage, caption, add_location); // give user feedback of the event gViewerWindow->playSnapshotAnimAndSound(); + LLUploadDialog::modalUploadDialog(getString("upload_message")); // don't destroy the window until the upload is done // this way we keep the information in the form setVisible(FALSE); - - // remove any dependency on snapshot floater - // so we outlive it during the upload. - LLFloater* dependee = getDependee(); - if (dependee) - { - dependee->removeDependentFloater(this); - } } else { diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 512af5f2f..217d1ebda 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -345,27 +345,6 @@ BOOL stop_gloderror() return FALSE; } -LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) -{ - mMP = mp; - mLOD = lod; - open(FFLOAD_COLLADA); - run(boost::bind(&LLMeshFilePicker::loadFromCollada, this)); -} - -// static -void LLMeshFilePicker::loadFromCollada(LLMeshFilePicker* filepicker) -{ - LLMeshFilePicker* self = (LLMeshFilePicker*)filepicker; - if (self && filepicker->hasFilename()) - self->notify(filepicker->getFilename()); -} - -void LLMeshFilePicker::notify(const std::string& filename) -{ - mMP->loadModel(filename, mLOD); -} - //----------------------------------------------------------------------------- // LLFloaterModelPreview() //----------------------------------------------------------------------------- @@ -583,7 +562,19 @@ void LLFloaterModelPreview::loadModel(S32 lod) { mModelPreview->mLoading = true; - new LLMeshFilePicker(mModelPreview, lod); + AIFilePicker* filepicker = AIFilePicker::create(); + filepicker->open(FFLOAD_COLLADA, "", "mesh"); + filepicker->run(boost::bind(&LLFloaterModelPreview::loadModel_continued, this, filepicker, lod)); +} + +void LLFloaterModelPreview::loadModel_continued(AIFilePicker* filepicker, S32 lod) +{ + std::string filename; + if (filepicker->hasFilename()) // User did not click Cancel? + { + filename = filepicker->getFilename(); + } + mModelPreview->loadModel(filename, lod); // Pass an empty filename if the user clicked Cancel. } void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index f81552f4f..6ca55bb81 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -187,6 +187,7 @@ public: void refresh(); void loadModel(S32 lod); + void loadModel_continued(AIFilePicker* filepicker, S32 lod); void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false); void onViewOptionChecked(LLUICtrl* ctrl); @@ -212,7 +213,6 @@ public: protected: friend class LLModelPreview; - friend class LLMeshFilePicker; friend class LLPhysicsDecomp; static void onImportScaleCommit(LLUICtrl*, void*); @@ -292,18 +292,6 @@ private: LLButton* mCalculateBtn; }; -class LLMeshFilePicker : public AIFilePicker -{ -public: - LLMeshFilePicker(LLModelPreview* mp, S32 lod); - static void loadFromCollada(LLMeshFilePicker* filepicker); - virtual void notify(const std::string& filename); - -private: - LLModelPreview* mMP; - S32 mLOD; -}; - class LLModelPreview : public LLViewerDynamicTexture, public LLMutex { typedef boost::signals2::signal details_signal_t; diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 132bc5d73..6c05f60a5 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -223,7 +223,6 @@ void LLFloaterPostcard::onClickCancel(void* data) if (data) { LLFloaterPostcard *self = (LLFloaterPostcard *)data; - LLFloaterSnapshot::savePostcardDone(false, self->mSnapshotIndex); self->close(false); } } @@ -410,6 +409,7 @@ void LLFloaterPostcard::sendPostcard() LLVFile::writeFile(mJPEGImage->getData(), mJPEGImage->getDataSize(), gVFS, mAssetID, LLAssetType::AT_IMAGE_JPEG); // upload the image + LLFloaterSnapshot::saveStart(mSnapshotIndex); std::string url = gAgent.getRegion()->getCapability("SendPostcard"); if(!url.empty()) { @@ -436,11 +436,4 @@ void LLFloaterPostcard::sendPostcard() // don't destroy the window until the upload is done // this way we keep the information in the form setVisible(FALSE); - - // also remove any dependency on another floater - // so that we can be sure to outlive it while we - // need to. - LLFloater* dependee = getDependee(); - if (dependee) - dependee->removeDependentFloater(this); } diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 6dcf63a74..00701a11b 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -181,12 +181,10 @@ public: LLFloaterFeed* getCaptionAndSaveFeed(); LLFloaterPostcard* savePostcard(); void saveTexture(); - void saveTextureDone(bool success, int index); static void saveTextureDone(LLUUID const& asset_id, void* user_data, S32 status, LLExtStat ext_status); void saveLocal(); - void saveLocalDone(bool success, int index); - void saveFeedDone(bool success, int index); - void savePostcardDone(bool success, int index); + void saveStart(int index); + void saveDone(ESnapshotType type, bool success, int index); void close(LLFloaterSnapshot* view); void doCloseAfterSave(); @@ -265,16 +263,93 @@ private: BOOL mSnapshotActive; LLViewerWindow::ESnapshotType mSnapshotBufferType; - bool mCallbackHappened; - bool mSaveSuccessful; + int mOutstandingCallbacks; + int mSaveFailures; LLFloaterSnapshot* mCloseCalled; - int mSnapshotIndex; + static int sSnapshotIndex; public: static std::set sList; LLFrameTimer mFormattedDelayTimer; }; +///---------------------------------------------------------------------------- +/// Class LLFloaterSnapshot::Impl +///---------------------------------------------------------------------------- +class LLFloaterSnapshot::Impl +{ +public: + Impl() + : mAvatarPauseHandles(), + mLastToolset(NULL) + { + } + ~Impl() + { + //unpause avatars + mAvatarPauseHandles.clear(); + mQualityMouseUpConnection.disconnect(); + } + static void onClickKeep(void* data); + static void onCommitSave(LLUICtrl* ctrl, void* data); + static void onClickNewSnapshot(void* data); + static void onClickFreezeTime(void* data); + static void onClickAutoSnap(LLUICtrl *ctrl, void* data); + static void onClickTemporaryImage(LLUICtrl *ctrl, void* data); + //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); + static void onClickLess(void* data) ; + static void onClickMore(void* data) ; + static void onClickUICheck(LLUICtrl *ctrl, void* data); + static void onClickHUDCheck(LLUICtrl *ctrl, void* data); + static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); + static void onCommitQuality(LLUICtrl* ctrl, void* data); + static void onCommitFeedResolution(LLUICtrl* ctrl, void* data); + static void onCommitPostcardResolution(LLUICtrl* ctrl, void* data); + static void onCommitTextureResolution(LLUICtrl* ctrl, void* data); + static void onCommitLocalResolution(LLUICtrl* ctrl, void* data); + static void onCommitFeedAspect(LLUICtrl* ctrl, void* data); + static void onCommitPostcardAspect(LLUICtrl* ctrl, void* data); + static void onCommitTextureAspect(LLUICtrl* ctrl, void* data); + static void onCommitLocalAspect(LLUICtrl* ctrl, void* data); + static void updateResolution(LLUICtrl* ctrl, void* data, bool update_controls = true); + static void updateAspect(LLUICtrl* ctrl, void* data, bool update_controls = true); + static void onCommitFreezeTime(LLUICtrl* ctrl, void* data); + static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); + static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); + static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data); + static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); + static void onCommitCustomAspect(LLUICtrl *ctrl, void* data); + static void onQualityMouseUp(void* data); + + static LLSnapshotLivePreview* getPreviewView(void); + static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool visible, bool update_controls = true); + static void setAspect(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls = true); + static void updateControls(LLFloaterSnapshot* floater, bool delayed_formatted = false); + static void resetFeedAndPostcardAspect(LLFloaterSnapshot* floater); + static void updateLayout(LLFloaterSnapshot* floater); + static void freezeTime(bool on); + + static LLHandle sPreviewHandle; + +private: + static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); + static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater); + static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); + static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); + +public: + std::vector mAvatarPauseHandles; + + LLToolset* mLastToolset; + boost::signals2::connection mQualityMouseUpConnection; +}; + +//---------------------------------------------------------------------------- +// LLSnapshotLivePreview + +//static +int LLSnapshotLivePreview::sSnapshotIndex; + void LLSnapshotLivePreview::setSnapshotBufferType(LLFloaterSnapshot* floater, LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; @@ -332,8 +407,7 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), mSnapshotActive(FALSE), mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR), - mCloseCalled(NULL), - mSnapshotIndex(0) + mCloseCalled(NULL) { DoutEntering(dc::notice, "LLSnapshotLivePreview() [" << (void*)this << "]"); setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")); @@ -357,10 +431,9 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : LLSnapshotLivePreview::~LLSnapshotLivePreview() { DoutEntering(dc::notice, "~LLSnapshotLivePreview() [" << (void*)this << "]"); - // delete images - mRawSnapshot = NULL; - mFormattedImage = NULL; sList.erase(this); + // Stop callbacks from using this object. + ++sSnapshotIndex; } void LLSnapshotLivePreview::setMaxImageSize(S32 size) @@ -831,7 +904,19 @@ BOOL LLSnapshotLivePreview::onIdle(LLSnapshotLivePreview* previewp) // Grab the raw image and encode it into desired format. Dout(dc::notice, "LLSnapshotLivePreview::onIdle: Actually making a new snapshot!"); - previewp->mSnapshotIndex++; + + // This should never happen, but well. If it's true then that means that the + // snapshot floater is disabled. Incrementing sSnapshotIndex will cause the + // callbacks to be ignored, so we better make sure that the floater is enabled. + if (previewp->mCloseCalled) + { + previewp->mCloseCalled->setEnabled(TRUE); + } + previewp->sSnapshotIndex++; + Dout(dc::notice, "sSnapshotIndex is now " << previewp->sSnapshotIndex << "; mOutstandingCallbacks reset to 0."); + previewp->mOutstandingCallbacks = 0; // There are no outstanding callbacks for THIS snapshot. + previewp->mSaveFailures = 0; // There were no upload failures (or attempts for that matter) for this snapshot. + previewp->mFormattedImage = NULL; previewp->mFormattedUpToDate = false; previewp->mUsedBy = 0; // This snapshot wasn't used yet. @@ -1225,15 +1310,16 @@ LLFloaterFeed* LLSnapshotLivePreview::getCaptionAndSaveFeed() return NULL; } - mCallbackHappened = false; - mSaveSuccessful = false; + ++mOutstandingCallbacks; + mSaveFailures = 0; addUsedBy(SNAPSHOT_FEED); + Dout(dc::notice, "LLSnapshotLivePreview::getCaptionAndSaveFeed: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); if (mFullScreenPreviewTexture.isNull()) { // This should never happen! llwarns << "The snapshot image has not been generated!" << llendl; - saveFeedDone(false, mSnapshotIndex); + saveDone(SNAPSHOT_FEED, false, sSnapshotIndex); return NULL; } @@ -1246,11 +1332,11 @@ LLFloaterFeed* LLSnapshotLivePreview::getCaptionAndSaveFeed() if (!png) { llwarns << "Formatted image not a PNG" << llendl; - saveFeedDone(false, mSnapshotIndex); + saveDone(SNAPSHOT_FEED, false, sSnapshotIndex); return NULL; } - LLFloaterFeed* floater = LLFloaterFeed::showFromSnapshot(png, mFullScreenPreviewTexture, image_scale, mSnapshotIndex); + LLFloaterFeed* floater = LLFloaterFeed::showFromSnapshot(png, mFullScreenPreviewTexture, image_scale, sSnapshotIndex); return floater; } @@ -1262,15 +1348,16 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() return NULL; } - mCallbackHappened = false; - mSaveSuccessful = false; + ++mOutstandingCallbacks; + mSaveFailures = 0; addUsedBy(SNAPSHOT_POSTCARD); + Dout(dc::notice, "LLSnapshotLivePreview::savePostcard: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); if(mFullScreenPreviewTexture.isNull()) { //this should never happen!! llwarns << "The snapshot image has not been generated!" << llendl ; - savePostcardDone(false, mSnapshotIndex); + saveDone(SNAPSHOT_POSTCARD, false, sSnapshotIndex); return NULL ; } @@ -1285,10 +1372,10 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() if(!jpg) { llwarns << "Formatted image not a JPEG" << llendl; - savePostcardDone(false, mSnapshotIndex); + saveDone(SNAPSHOT_POSTCARD, false, sSnapshotIndex); return NULL; } - LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mFullScreenPreviewTexture, image_scale, mPosTakenGlobal, mSnapshotIndex); + LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mFullScreenPreviewTexture, image_scale, mPosTakenGlobal, sSnapshotIndex); return floater; } @@ -1307,9 +1394,11 @@ void LLSnapshotLivePreview::saveTexture() return; } - mCallbackHappened = false; - mSaveSuccessful = false; + ++mOutstandingCallbacks; + mSaveFailures = 0; addUsedBy(SNAPSHOT_TEXTURE); + Dout(dc::notice, "LLSnapshotLivePreview::saveTexture: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + saveStart(sSnapshotIndex); // gen a new uuid for this asset LLTransactionID tid; @@ -1333,7 +1422,7 @@ void LLSnapshotLivePreview::saveTexture() LLFloaterPerms::getGroupPerms(), // that is more permissive than other uploads LLFloaterPerms::getEveryonePerms(), "Snapshot : " + pos_string, - callback, expected_upload_cost, new saveTextureUserData(this, mSnapshotIndex)); + callback, expected_upload_cost, new saveTextureUserData(this, sSnapshotIndex)); gViewerWindow->playSnapshotAnimAndSound(); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); @@ -1346,17 +1435,20 @@ void LLSnapshotLivePreview::saveLocal() return; } - mCallbackHappened = false; - mSaveSuccessful = false; + ++mOutstandingCallbacks; + mSaveFailures = 0; addUsedBy(SNAPSHOT_LOCAL); + Dout(dc::notice, "LLSnapshotLivePreview::saveLocal: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + saveStart(sSnapshotIndex); - gViewerWindow->saveImageNumbered(mFormattedImage, mSnapshotIndex); // This calls saveLocalDone() immediately, or later. + gViewerWindow->saveImageNumbered(mFormattedImage, sSnapshotIndex); // This calls saveDone() immediately, or later. } void LLSnapshotLivePreview::close(LLFloaterSnapshot* view) { + DoutEntering(dc::notice, "LLSnapshotLivePreview::close(" << (void*)view << ") [mOutstandingCallbacks = " << mOutstandingCallbacks << "]"); mCloseCalled = view; - if (mCallbackHappened) + if (!mOutstandingCallbacks) { doCloseAfterSave(); } @@ -1366,79 +1458,51 @@ void LLSnapshotLivePreview::close(LLFloaterSnapshot* view) } } -void LLSnapshotLivePreview::saveFeedDone(bool success, int index) +void LLSnapshotLivePreview::saveStart(int index) { - if (mSnapshotIndex != index) + if (index == sSnapshotIndex && gSavedSettings.getBOOL("CloseSnapshotOnKeep") && gSavedSettings.getBOOL("FreezeTime")) { - // The snapshot was already replaced, so this callback has nothing to do with us anymore. - if (!success) - { - llwarns << "Permanent failure to upload snapshot" << llendl; - } - return; - } + // Turn off Freeze Time if we're going to close the floater + // anyway at the *start* of an upload/save attempt. + // + // The disadvantage is that if the upload fails then we lost the Frozen Scene. + // The user can still retry to upload or save the snapshot using the same size + // (or smaller) to disk. + // + // The advantage is that if for some reason the upload takes a long time, then + // the user can immediately continue with using the viewer instead of ending + // up with a frozen (haha) interface. - mCallbackHappened = true; - mSaveSuccessful = success; - if (!success) - { - // Enable Upload button. - delUsedBy(SNAPSHOT_FEED); - LLFloaterSnapshot::updateControls(); - } - if (mCloseCalled) - { - doCloseAfterSave(); + LLFloaterSnapshot::Impl::freezeTime(false); } } -void LLSnapshotLivePreview::savePostcardDone(bool success, int index) +void LLSnapshotLivePreview::saveDone(ESnapshotType type, bool success, int index) { - if (mSnapshotIndex != index) + DoutEntering(dc::notice, "LLSnapshotLivePreview::saveDone(" << type << ", " << success << ", " << index << ")"); + + if (sSnapshotIndex != index) { + Dout(dc::notice, "sSnapshotIndex (" << sSnapshotIndex << ") != index (" << index << ")"); + // The snapshot was already replaced, so this callback has nothing to do with us anymore. if (!success) { - llwarns << "Permanent failure to email snapshot" << llendl; + llwarns << "Permanent failure to upload or save snapshot" << llendl; } return; } - mCallbackHappened = true; - mSaveSuccessful = success; + --mOutstandingCallbacks; + Dout(dc::notice, "sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); if (!success) { + ++mSaveFailures; // Enable Upload button. - delUsedBy(SNAPSHOT_POSTCARD); + delUsedBy(type); LLFloaterSnapshot::updateControls(); } - if (mCloseCalled) - { - doCloseAfterSave(); - } -} - -void LLSnapshotLivePreview::saveTextureDone(bool success, int index) -{ - if (mSnapshotIndex != index) - { - // The snapshot was already replaced, so this callback has nothing to do with us anymore. - if (!success) - { - llwarns << "Permanent failure to upload texture" << llendl; - } - return; - } - - mCallbackHappened = true; - mSaveSuccessful = success; - if (!success) - { - // Enable Upload button. - delUsedBy(LLSnapshotLivePreview::SNAPSHOT_TEXTURE); - LLFloaterSnapshot::updateControls(); - } - if (mCloseCalled) + if (!mOutstandingCallbacks) { doCloseAfterSave(); } @@ -1455,39 +1519,17 @@ void LLSnapshotLivePreview::saveTextureDone(LLUUID const& asset_id, void* user_d LLNotificationsUtil::add("UploadSnapshotFail", args); } saveTextureUserData* data = (saveTextureUserData*)user_data; - data->mSelf->saveTextureDone(success, data->mSnapshotIndex); + data->mSelf->saveDone(SNAPSHOT_TEXTURE, success, data->mSnapshotIndex); delete data; } -void LLSnapshotLivePreview::saveLocalDone(bool success, int index) -{ - if (mSnapshotIndex != index) - { - // The snapshot was already replaced, so this callback has nothing to do with us anymore. - if (!success) - { - llwarns << "Permanent failure to save snapshot." << llendl; - } - return; - } - - mCallbackHappened = true; - mSaveSuccessful = success; - if (!success) - { - // Enable Save button. - delUsedBy(SNAPSHOT_LOCAL); - LLFloaterSnapshot::updateControls(); - } - if (mCloseCalled) - { - doCloseAfterSave(); - } -} - void LLSnapshotLivePreview::doCloseAfterSave() { - if (mSaveSuccessful) + if (!mCloseCalled) + { + return; + } + if (!mSaveFailures && gSavedSettings.getBOOL("CloseSnapshotOnKeep")) { // Relinquish image memory. mFormattedImage = NULL; @@ -1503,82 +1545,14 @@ void LLSnapshotLivePreview::doCloseAfterSave() } } -///---------------------------------------------------------------------------- -/// Class LLFloaterSnapshot::Impl -///---------------------------------------------------------------------------- - -class LLFloaterSnapshot::Impl -{ -public: - Impl() - : mAvatarPauseHandles(), - mLastToolset(NULL) - { - } - ~Impl() - { - //unpause avatars - mAvatarPauseHandles.clear(); - mQualityMouseUpConnection.disconnect(); - } - static void onClickKeep(void* data); - static void onCommitSave(LLUICtrl* ctrl, void* data); - static void onClickNewSnapshot(void* data); - static void onClickFreezeTime(void* data); - static void onClickAutoSnap(LLUICtrl *ctrl, void* data); - static void onClickTemporaryImage(LLUICtrl *ctrl, void* data); - //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); - static void onClickLess(void* data) ; - static void onClickMore(void* data) ; - static void onClickUICheck(LLUICtrl *ctrl, void* data); - static void onClickHUDCheck(LLUICtrl *ctrl, void* data); - static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); - static void onCommitQuality(LLUICtrl* ctrl, void* data); - static void onCommitFeedResolution(LLUICtrl* ctrl, void* data); - static void onCommitPostcardResolution(LLUICtrl* ctrl, void* data); - static void onCommitTextureResolution(LLUICtrl* ctrl, void* data); - static void onCommitLocalResolution(LLUICtrl* ctrl, void* data); - static void onCommitFeedAspect(LLUICtrl* ctrl, void* data); - static void onCommitPostcardAspect(LLUICtrl* ctrl, void* data); - static void onCommitTextureAspect(LLUICtrl* ctrl, void* data); - static void onCommitLocalAspect(LLUICtrl* ctrl, void* data); - static void updateResolution(LLUICtrl* ctrl, void* data, bool update_controls = true); - static void updateAspect(LLUICtrl* ctrl, void* data, bool update_controls = true); - static void onCommitFreezeTime(LLUICtrl* ctrl, void* data); - static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); - static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); - static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data); - static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); - static void onCommitCustomAspect(LLUICtrl *ctrl, void* data); - static void onQualityMouseUp(void* data); - - static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater); - static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool visible, bool update_controls = true); - static void setAspect(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls = true); - static void updateControls(LLFloaterSnapshot* floater, bool delayed_formatted = false); - static void resetFeedAndPostcardAspect(LLFloaterSnapshot* floater); - static void updateLayout(LLFloaterSnapshot* floater); - - static LLHandle sPreviewHandle; - -private: - static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); - static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater); - static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); - static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); - -public: - std::vector mAvatarPauseHandles; - - LLToolset* mLastToolset; - boost::signals2::connection mQualityMouseUpConnection; -}; +//---------------------------------------------------------------------------- +// LLFloaterSnapshot::Impl // static LLHandle LLFloaterSnapshot::Impl::sPreviewHandle; // static -LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater) +LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(void) { LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)sPreviewHandle.get(); return previewp; @@ -1646,11 +1620,8 @@ void LLFloaterSnapshot::Impl::resetFeedAndPostcardAspect(LLFloaterSnapshot* floa //static void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) { - LLSnapshotLivePreview* previewp = getPreviewView(floaterp); - - S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong() ; - - if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution + S32 delta_height = 0; + if (!gSavedSettings.getBOOL("AdvanceSnapshot")) { floaterp->getChild("feed_size_combo")->setCurrentByIndex(2); // 500x375 gSavedSettings.setS32("SnapshotFeedLastResolution", 2); @@ -1671,15 +1642,20 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) gSavedSettings.setS32("SnapshotLocalLastAspect", 0); updateControls(floaterp); - } - if (gSavedSettings.getBOOL("UseFreezeTime")) + delta_height = floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong(); + } + floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); +} + +//static +void LLFloaterSnapshot::Impl::freezeTime(bool on) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (on) { // stop all mouse events at fullscreen preview layer - floaterp->getParent()->setMouseOpaque(TRUE); - - // shrink to smaller layout - floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); + sInstance->getParent()->setMouseOpaque(TRUE); // can see and interact with fullscreen preview now if (previewp) @@ -1706,8 +1682,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) } else // turning off freeze frame mode { - floaterp->getParent()->setMouseOpaque(FALSE); - floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); + sInstance->getParent()->setMouseOpaque(FALSE); if (previewp) { previewp->setVisible(FALSE); @@ -1781,7 +1756,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater, bool de floater->childSetVisible("local_size_combo", FALSE); floater->childSetVisible("local_aspect_combo", FALSE); - LLSnapshotLivePreview* previewp = getPreviewView(floater); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { previewp->setSnapshotType(shot_type); @@ -1910,8 +1885,7 @@ void LLFloaterSnapshot::Impl::onCommitFeedResolution(LLUICtrl* ctrl, void* data) { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotFeedLastResolution", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_FEED); @@ -1924,8 +1898,7 @@ void LLFloaterSnapshot::Impl::onCommitPostcardResolution(LLUICtrl* ctrl, void* d { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotPostcardLastResolution", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_POSTCARD); @@ -1938,8 +1911,7 @@ void LLFloaterSnapshot::Impl::onCommitTextureResolution(LLUICtrl* ctrl, void* da { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotTextureLastResolution", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_TEXTURE); @@ -1952,8 +1924,7 @@ void LLFloaterSnapshot::Impl::onCommitLocalResolution(LLUICtrl* ctrl, void* data { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotLocalLastResolution", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_LOCAL); @@ -1966,8 +1937,7 @@ void LLFloaterSnapshot::Impl::onCommitFeedAspect(LLUICtrl* ctrl, void* data) { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotFeedLastAspect", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_FEED); @@ -1980,8 +1950,7 @@ void LLFloaterSnapshot::Impl::onCommitPostcardAspect(LLUICtrl* ctrl, void* data) { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotPostcardLastAspect", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_POSTCARD); @@ -1994,8 +1963,7 @@ void LLFloaterSnapshot::Impl::onCommitTextureAspect(LLUICtrl* ctrl, void* data) { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotTextureLastAspect", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_TEXTURE); @@ -2008,8 +1976,7 @@ void LLFloaterSnapshot::Impl::onCommitLocalAspect(LLUICtrl* ctrl, void* data) { LLComboBox* combobox = (LLComboBox*)ctrl; gSavedSettings.setS32("SnapshotLocalLastAspect", combobox->getCurrentIndex()); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && previewp->isUsed()) { previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_LOCAL); @@ -2027,67 +1994,79 @@ void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data) onClickKeep(data); } +//static +void LLFloaterSnapshot::saveStart(int index) +{ + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp) + { + previewp->saveStart(index); + } +} + // Called from LLViewerWindow::saveImageNumbered, LLViewerWindow::saveImageNumbered_continued1 and LLViewerWindow::saveImageNumbered_continued2. //static void LLFloaterSnapshot::saveLocalDone(bool success, int index) { - LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(sInstance); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); if (previewp) { - previewp->saveLocalDone(success, index); + previewp->saveDone(LLSnapshotLivePreview::SNAPSHOT_LOCAL, success, index); } } //static void LLFloaterSnapshot::saveFeedDone(bool success, int index) { - LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(sInstance); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); if (previewp) { - previewp->saveFeedDone(success, index); + previewp->saveDone(LLSnapshotLivePreview::SNAPSHOT_FEED, success, index); } } //static void LLFloaterSnapshot::savePostcardDone(bool success, int index) { - LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(sInstance); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); if (previewp) { - previewp->savePostcardDone(success, index); + previewp->saveDone(LLSnapshotLivePreview::SNAPSHOT_POSTCARD, success, index); } } // static void LLFloaterSnapshot::Impl::onClickKeep(void* data) { - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLFloaterSnapshot* floater = (LLFloaterSnapshot *)data; + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_FEED) { LLFloaterFeed* floater = previewp->getCaptionAndSaveFeed(); - // If still in snapshot mode, put feed floater in snapshot floaterview - // and link it to snapshot floater. - if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep")) + if (floater) { - gFloaterView->removeChild(floater); + // Make sure that the new floater is in front of gSnapshotFloaterView. + // So that the structure is: + // "root" --> + // "Snapshot Floater View" --> + // "floater_snapshot_profile" + // "Snapshot" floater + // ["snapshot_live_preview"] + // and "floater_snapshot_profile" (floater) is a child of "Snapshot Floater View" (gSnapshotFloaterView), + // and therefore in front of "snapshot_live_preview", if it exists. gSnapshotFloaterView->addChild(floater); - view->addDependentFloater(floater, FALSE); } } else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) { LLFloaterPostcard* floater = previewp->savePostcard(); - // if still in snapshot mode, put postcard floater in snapshot floaterview - // and link it to snapshot floater - if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep")) + if (floater) { - gFloaterView->removeChild(floater); + // Same as above, but for the "Postcard" floater. gSnapshotFloaterView->addChild(floater); - view->addDependentFloater(floater, FALSE); } } else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) @@ -2101,37 +2080,34 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data) if (gSavedSettings.getBOOL("CloseSnapshotOnKeep")) { - previewp->close(view); + previewp->close(floater); } else { checkAutoSnapshot(previewp); } - updateControls(view); + updateControls(floater); } } // static void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data) { - LLFloaterSnapshot* view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); - if (previewp && view) + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) { previewp->updateSnapshot(TRUE); } } // static -void LLFloaterSnapshot::Impl::onClickFreezeTime(void* data) +void LLFloaterSnapshot::Impl::onClickFreezeTime(void*) { - LLFloaterSnapshot* view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); - if (previewp && view) + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) { - gSavedSettings.setBOOL("UseFreezeTime", TRUE); - updateLayout(view); + freezeTime(true); } } @@ -2141,11 +2117,11 @@ void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data) LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; gSavedSettings.setBOOL( "AutoSnapshot", check->get() ); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) + LLFloaterSnapshot* floater = (LLFloaterSnapshot*)data; + if (floater) { - checkAutoSnapshot(getPreviewView(view)); - updateControls(view); + checkAutoSnapshot(getPreviewView()); + updateControls(floater); } } @@ -2170,9 +2146,9 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data) view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong()); updateControls(view) ; updateLayout(view) ; - if(getPreviewView(view)) + if (getPreviewView()) { - getPreviewView(view)->setThumbnailImageSize() ; + getPreviewView()->setThumbnailImageSize() ; } } } @@ -2187,9 +2163,9 @@ void LLFloaterSnapshot::Impl::onClickLess(void* data) view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort()); updateControls(view) ; updateLayout(view) ; - if(getPreviewView(view)) + if (getPreviewView()) { - getPreviewView(view)->setThumbnailImageSize() ; + getPreviewView()->setThumbnailImageSize(); } } } @@ -2203,7 +2179,7 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view), TRUE); + checkAutoSnapshot(getPreviewView(), TRUE); updateControls(view); } } @@ -2217,7 +2193,7 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view), TRUE); + checkAutoSnapshot(getPreviewView(), TRUE); updateControls(view); } } @@ -2236,15 +2212,11 @@ void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data) LLSliderCtrl* slider = (LLSliderCtrl*)ctrl; S32 quality_val = llfloor((F32)slider->getValue().asReal()); - LLFloaterSnapshot* view = (LLFloaterSnapshot *)data; - if (view) + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) { - LLSnapshotLivePreview* previewp = getPreviewView(view); - if (previewp) - { - previewp->setSnapshotQuality(quality_val); - checkAutoSnapshot(previewp, TRUE); - } + previewp->setSnapshotQuality(quality_val); + checkAutoSnapshot(previewp, TRUE); } } @@ -2317,7 +2289,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool S32 new_width = 0; S32 new_height = 0; F32 new_aspect = 0; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); #if 0 // Broken -- not doing this for now. LLSnapshotLivePreview::ESnapshotType shot_type = (LLSnapshotLivePreview::ESnapshotType)gSavedSettings.getS32("LastSnapshotType"); @@ -2595,7 +2567,7 @@ void LLFloaterSnapshot::Impl::updateAspect(LLUICtrl* ctrl, void* data, bool upda return; } - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); view->getChild("feed_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastAspect")); view->getChild("postcard_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastAspect")); @@ -2742,7 +2714,7 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat S32 w = llround(view->childGetValue("snapshot_width").asReal(), 1.0); S32 h = llround(view->childGetValue("snapshot_height").asReal(), 1.0); - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { S32 curw,curh; @@ -2799,7 +2771,7 @@ void LLFloaterSnapshot::Impl::onCommitCustomAspect(LLUICtrl *ctrl, void* data) { F32 a = view->childGetValue("aspect_ratio").asReal(); - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { F32 cura = previewp->getAspect(); @@ -2912,18 +2884,21 @@ BOOL LLFloaterSnapshot::postBuild() // create preview window LLRect full_screen_rect = sInstance->getRootView()->getRect(); LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(full_screen_rect); - sInstance->getRootView()->removeChild(gSnapshotFloaterView); - // make sure preview is below snapshot floater - sInstance->getRootView()->addChild(previewp); - sInstance->getRootView()->addChild(gSnapshotFloaterView); + // Make sure preview is below snapshot floater. + // "root" --> (first child is hit first): + // "Snapshot Floater View" + // "snapshot_live_preview" + // ... + sInstance->getRootView()->addChild(previewp); // Note that addChild is actually 'moveChild'. + sInstance->getRootView()->addChild(gSnapshotFloaterView); // The last added child becomes the first child; the one up front. - gSavedSettings.setBOOL("UseFreezeTime", gSavedSettings.getBOOL("SnapshotOpenFreezeTime")); gSavedSettings.setBOOL("TemporaryUpload",FALSE); childSetValue("temp_check",FALSE); Impl::sPreviewHandle = previewp->getHandle(); impl.updateControls(this); + impl.freezeTime(gSavedSettings.getBOOL("SnapshotOpenFreezeTime")); return TRUE; } @@ -2936,7 +2911,7 @@ LLRect LLFloaterSnapshot::getThumbnailAreaRect() void LLFloaterSnapshot::draw() { - LLSnapshotLivePreview* previewp = impl.getPreviewView(this); + LLSnapshotLivePreview* previewp = impl.getPreviewView(); if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) { @@ -2977,8 +2952,7 @@ void LLFloaterSnapshot::onClose(bool app_quitting) // Set invisible so it doesn't eat tooltips. JC gSnapshotFloaterView->setVisible(FALSE); gSavedSettings.setBOOL("SnapshotBtnState", FALSE); - gSavedSettings.setBOOL("UseFreezeTime", FALSE); - impl.updateLayout(this); + impl.freezeTime(false); destroy(); } @@ -2988,9 +2962,17 @@ void LLFloaterSnapshot::show(void*) if (!sInstance) { sInstance = new LLFloaterSnapshot(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE); - //move snapshot floater to special purpose snapshotfloaterview - gFloaterView->removeChild(sInstance); + LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE); // "Snapshot" floater. + // Make snapshot floater a child of (full screen) gSnapshotFloaterView. + // So that the structure is: + // "root" --> + // "Snapshot Floater View" --> + // "Snapshot" floater + // ["floater_snapshot_profile"] + // ["Postcard"] + // ["snapshot_live_preview"] + // and the "Snapshot" floater (sInstance) is a child of "Snapshot Floater View" (gSnapshotFloaterView), + // and therefore in front of "snapshot_live_preview", if it exists. gSnapshotFloaterView->addChild(sInstance); sInstance->impl.updateLayout(sInstance); @@ -3047,28 +3029,26 @@ BOOL LLFloaterSnapshot::handleKeyHere(KEY key, MASK mask) // However, if we're showing the fullscreen frozen preview, drop out of it; // otherwise leave Freeze Time (so the next ESC press DOES defocus // the floater and only the fourth will finally reset the cam). - LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(this); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); if (previewp && previewp->getShowFreezeFrameSnapshot()) { previewp->showFreezeFrameSnapshot(false); } else { - gSavedSettings.setBOOL("UseFreezeTime", FALSE); - impl.updateLayout(this); + impl.freezeTime(false); } return TRUE; } else if (key == 'Q' && mask == MASK_CONTROL) { // Allow users to quit with ctrl-Q. - LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(this); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); if (previewp && previewp->getShowFreezeFrameSnapshot()) { previewp->showFreezeFrameSnapshot(false); } - gSavedSettings.setBOOL("UseFreezeTime", FALSE); - impl.updateLayout(this); + impl.freezeTime(false); gFocusMgr.removeKeyboardFocusWithoutCallback(gFocusMgr.getKeyboardFocus()); return FALSE; } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index a2ad6f385..3b4f79ced 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -72,6 +72,7 @@ public: static S32 getUIWinHeightShort() {return sUIWinHeightShort ;} static S32 getUIWinWidth() {return sUIWinWidth ;} + static void saveStart(int index); static void saveLocalDone(bool success, int index); static void saveFeedDone(bool success, int index); static void savePostcardDone(bool success, int index); @@ -79,8 +80,9 @@ public: static void updateControls(); static void resetFeedAndPostcardAspect(); -private: class Impl; + +private: Impl& impl; static LLFloaterSnapshot* sInstance; diff --git a/indra/newview/llinventorybackup.cpp b/indra/newview/llinventorybackup.cpp index 6963d4ff9..749c7fc36 100644 --- a/indra/newview/llinventorybackup.cpp +++ b/indra/newview/llinventorybackup.cpp @@ -175,7 +175,7 @@ ESaveFilter LLInventoryBackup::getSaveFilter(LLInventoryItem* item) return FFSAVE_OGG; case LLAssetType::AT_SCRIPT: case LLAssetType::AT_LSL_TEXT: - return FFSAVE_LSL; + return FFSAVE_SCRIPT; case LLAssetType::AT_ANIMATION: return FFSAVE_ANIMATN; case LLAssetType::AT_GESTURE: diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index f362b4bad..230622f06 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -37,9 +37,6 @@ #include "llcallbacklist.h" #include "lldatapacker.h" #include "llfasttimer.h" -#if MESH_IMPORT -#include "llfloatermodelpreview.h" -#endif //MESH_IMPORT #include "llfloaterperms.h" #include "lleconomy.h" #include "llimagej2c.h" @@ -3302,6 +3299,8 @@ public: { } + virtual ~ndDecompTracer() { } + virtual void trace( char const *a_strMsg ) { llinfos << a_strMsg << llendl; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 16eef86fd..bf2bd3fb4 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1811,7 +1811,7 @@ void LLPreviewLSL::saveAs() } AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(default_filename, FFSAVE_LSL); + filepicker->open(default_filename, FFSAVE_SCRIPT); filepicker->run(boost::bind(&LLPreviewLSL::saveAs_continued, this, filepicker)); } @@ -2774,7 +2774,7 @@ void LLLiveLSLEditor::saveAs() } AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(default_filename, FFSAVE_LSL); + filepicker->open(default_filename, FFSAVE_SCRIPT); filepicker->run(boost::bind(&LLLiveLSLEditor::saveAs_continued, this, filepicker)); } diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index e08968f42..c24b37a26 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -815,7 +815,7 @@ void LLObjectBackup::importObject(bool upload) mRetexture = upload; // Open the file open dialog - AIFilePicker* filepicker = new AIFilePicker; + AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open(FFLOAD_XML, "", "import"); filepicker->run(boost::bind(&LLObjectBackup::importObject_continued, this, filepicker)); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 681cfd4fd..0ac9c8fcc 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1623,9 +1623,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) //capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp) capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); -#if MESH_IMPORT capabilityNames.append("MeshUploadFlag"); -#endif //MESH_IMPORT capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); /*capabilityNames.append("ObjectMedia"); diff --git a/indra/newview/skins/default/xui/en-us/floater_model_preview.xml b/indra/newview/skins/default/xui/en-us/floater_model_preview.xml index 19d26cbca..87481f4bb 100644 --- a/indra/newview/skins/default/xui/en-us/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en-us/floater_model_preview.xml @@ -1,5 +1,5 @@ - diff --git a/indra/newview/skins/default/xui/en-us/floater_snapshot_feed.xml b/indra/newview/skins/default/xui/en-us/floater_snapshot_feed.xml index 6322c447d..50bc3ae12 100644 --- a/indra/newview/skins/default/xui/en-us/floater_snapshot_feed.xml +++ b/indra/newview/skins/default/xui/en-us/floater_snapshot_feed.xml @@ -46,4 +46,7 @@ name="post_btn" bottom_delta="0" width="100"/> + + "Uploading..." + diff --git a/indra/newview/statemachine/aifilepicker.cpp b/indra/newview/statemachine/aifilepicker.cpp index 35b069a78..a8f6b2a6b 100644 --- a/indra/newview/statemachine/aifilepicker.cpp +++ b/indra/newview/statemachine/aifilepicker.cpp @@ -147,9 +147,6 @@ void AIFilePicker::open(ELoadFilter filter, std::string const& default_path, std case FFLOAD_ANIM: mFilter = "anim"; break; - case FFLOAD_COLLADA: - mFilter = "dae"; - break; #ifdef _CORY_TESTING case FFLOAD_GEOMETRY: mFilter = "geometry"; @@ -164,6 +161,18 @@ void AIFilePicker::open(ELoadFilter filter, std::string const& default_path, std case FFLOAD_RAW: mFilter = "raw"; break; + case FFLOAD_MODEL: + mFilter = "model"; + break; + case FFLOAD_COLLADA: + mFilter = "collada"; + break; + case FFLOAD_SCRIPT: + mFilter = "script"; + break; + case FFLOAD_DICTIONARY: + mFilter = "dictionary"; + break; case FFLOAD_INVGZ: mFilter = "invgz"; break; @@ -237,8 +246,8 @@ void AIFilePicker::open(std::string const& filename, ESaveFilter filter, std::st case FFSAVE_GESTURE: mFilter = "gesture"; break; - case FFSAVE_LSL: - mFilter = "lsl"; + case FFSAVE_SCRIPT: + mFilter = "script"; break; case FFSAVE_SHAPE: mFilter = "shape"; diff --git a/indra/newview/statemachine/aifilepicker.h b/indra/newview/statemachine/aifilepicker.h index e8584d90d..a56a8677f 100644 --- a/indra/newview/statemachine/aifilepicker.h +++ b/indra/newview/statemachine/aifilepicker.h @@ -43,10 +43,13 @@ enum ELoadFilter FFLOAD_WAV, FFLOAD_IMAGE, FFLOAD_ANIM, - FFLOAD_COLLADA, FFLOAD_XML, FFLOAD_SLOBJECT, FFLOAD_RAW, + FFLOAD_MODEL, + FFLOAD_COLLADA, + FFLOAD_SCRIPT, + FFLOAD_DICTIONARY, FFLOAD_INVGZ, FFLOAD_AO, FFLOAD_BLACKLIST @@ -66,11 +69,11 @@ enum ESaveFilter FFSAVE_J2C, FFSAVE_PNG, FFSAVE_JPEG, + FFSAVE_SCRIPT, FFSAVE_ANIMATN, FFSAVE_OGG, FFSAVE_NOTECARD, FFSAVE_GESTURE, - FFSAVE_LSL, FFSAVE_SHAPE, FFSAVE_SKIN, FFSAVE_HAIR, diff --git a/indra/plugins/filepicker/basic_plugin_filepicker.cpp b/indra/plugins/filepicker/basic_plugin_filepicker.cpp index 7e3a4f0b0..6a5e20b33 100644 --- a/indra/plugins/filepicker/basic_plugin_filepicker.cpp +++ b/indra/plugins/filepicker/basic_plugin_filepicker.cpp @@ -88,6 +88,8 @@ static LLFilePicker::ESaveFilter str2savefilter(std::string const& filter) return LLFilePicker::FFSAVE_PNG; else if (filter == "jpeg") return LLFilePicker::FFSAVE_JPEG; + else if (filter == "script") + return LLFilePicker::FFSAVE_SCRIPT; else if (filter == "animatn") return LLFilePicker::FFSAVE_ANIMATN; else if (filter == "ogg") @@ -96,8 +98,6 @@ static LLFilePicker::ESaveFilter str2savefilter(std::string const& filter) return LLFilePicker::FFSAVE_NOTECARD; else if (filter == "gesture") return LLFilePicker::FFSAVE_GESTURE; - else if (filter == "lsl") - return LLFilePicker::FFSAVE_LSL; else if (filter == "shape") return LLFilePicker::FFSAVE_SHAPE; else if (filter == "skin") @@ -157,6 +157,14 @@ static LLFilePicker::ELoadFilter str2loadfilter(std::string const& filter) return LLFilePicker::FFLOAD_SLOBJECT; else if (filter == "raw") return LLFilePicker::FFLOAD_RAW; + else if (filter == "model") + return LLFilePicker::FFLOAD_MODEL; + else if (filter == "collada") + return LLFilePicker::FFLOAD_COLLADA; + else if (filter == "script") + return LLFilePicker::FFLOAD_SCRIPT; + else if (filter == "dictionary") + return LLFilePicker::FFLOAD_DICTIONARY; else if (filter == "invgz") return LLFilePicker::FFLOAD_INVGZ; else if (filter == "ao") diff --git a/indra/plugins/filepicker/llfilepicker.cpp b/indra/plugins/filepicker/llfilepicker.cpp index ed86e0f6e..75bc89013 100644 --- a/indra/plugins/filepicker/llfilepicker.cpp +++ b/indra/plugins/filepicker/llfilepicker.cpp @@ -50,12 +50,16 @@ LLFilePicker LLFilePicker::sInstance; #define BLACKLIST_FILTER L"Asset Blacklist (*.blacklist)\0*.blacklist\0" // #define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0" +#define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0" #ifdef _CORY_TESTING #define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0" #endif #define XML_FILTER L"XML files (*.xml)\0*.xml\0" #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" +#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" +#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" +#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" #endif // @@ -164,6 +168,10 @@ bool LLFilePickerBase::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = ANIM_FILTER \ L"\0"; break; + case FFLOAD_COLLADA: + mOFN.lpstrFilter = COLLADA_FILTER \ + L"\0"; + break; #ifdef _CORY_TESTING case FFLOAD_GEOMETRY: mOFN.lpstrFilter = GEOMETRY_FILTER \ @@ -182,6 +190,18 @@ bool LLFilePickerBase::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = RAW_FILTER \ L"\0"; break; + case FFLOAD_MODEL: + mOFN.lpstrFilter = MODEL_FILTER \ + L"\0"; + break; + case FFLOAD_SCRIPT: + mOFN.lpstrFilter = SCRIPT_FILTER \ + L"\0"; + break; + case FFLOAD_DICTIONARY: + mOFN.lpstrFilter = DICTIONARY_FILTER \ + L"\0"; + break; // case FFLOAD_INVGZ: mOFN.lpstrFilter = INVGZ_FILTER \ @@ -484,15 +504,13 @@ bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filena L"Gestures (*.gesture)\0*.gesture\0" \ L"\0"; break; - case FFSAVE_LSL: + case FFSAVE_SCRIPT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"lsl"; - mOFN.lpstrFilter = - L"LSL (*.lsl)\0*.lsl\0" \ - L"\0"; + mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0"; break; case FFSAVE_SHAPE: if(filename.empty()) @@ -762,6 +780,15 @@ Boolean LLFilePickerBase::navOpenFilterProc(AEDesc *theItem, void *info, void *c result = false; } } + else if (filter == FFLOAD_COLLADA) + { + if (fileInfo.filetype != 'DAE ' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) + ) + { + result = false; + } + } else if (filter == FFLOAD_XML) { if (fileInfo.filetype != 'XML ' && @@ -795,7 +822,25 @@ Boolean LLFilePickerBase::navOpenFilterProc(AEDesc *theItem, void *info, void *c result = false; } } - + else if (filter == FFLOAD_SCRIPT) + { + if (fileInfo.filetype != 'LSL ' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) + { + result = false; + } + } + else if (filter == FFLOAD_DICTIONARY) + { + if (fileInfo.filetype != 'DIC ' && + fileInfo.filetype != 'XCU ' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && + fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))) + { + result = false; + } + } + if (fileInfo.extension) { CFRelease(fileInfo.extension); @@ -985,6 +1030,12 @@ OSStatus LLFilePickerBase::doNavSaveDialog(ESaveFilter filter, std::string const extension = CFSTR(".j2c"); break; + case FFSAVE_SCRIPT: + type = 'LSL '; + creator = '\?\?\?\?'; + extension = CFSTR(".lsl"); + break; + case FFSAVE_ALL: default: type = '\?\?\?\?'; @@ -1349,6 +1400,12 @@ static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) LLTrans::getString("xml_file") + " (*.xml)"); } +static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", + LLTrans::getString("scene_files") + " (*.dae)"); +} + static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) { GtkFileFilter *gfilter = gtk_file_filter_new(); @@ -1362,6 +1419,17 @@ static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) return filtername; } +static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_mime_filter_to_gtkchooser(picker, "text/plain", + LLTrans::getString("script_files") + " (*.lsl)"); +} + +static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_mime_filter_to_gtkchooser(picker, "text/plain", + LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); +} bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filename, std::string const& folder) { @@ -1421,6 +1489,10 @@ bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filena LLTrans::getString("compressed_image_files") + " (*.j2c)"); suggest_ext = ".j2c"; break; + case FFSAVE_SCRIPT: + caption += add_script_filter_to_gtkchooser(picker); + suggest_ext = ".lsl"; + break; default:; break; } @@ -1475,9 +1547,18 @@ bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder case FFLOAD_ANIM: filtername = add_bvh_filter_to_gtkchooser(picker); break; + case FFLOAD_COLLADA: + filtername = add_collada_filter_to_gtkchooser(picker); + break; case FFLOAD_IMAGE: filtername = add_imageload_filter_to_gtkchooser(picker); break; + case FFLOAD_SCRIPT: + filtername = add_script_filter_to_gtkchooser(picker); + break; + case FFLOAD_DICTIONARY: + filtername = add_dictionary_filter_to_gtkchooser(picker); + break; case FFLOAD_XML: filtername = add_xml_filter_to_gtkchooser(picker); break; diff --git a/indra/plugins/filepicker/llfilepicker.h b/indra/plugins/filepicker/llfilepicker.h index 0ba7ff614..cb5a5f24d 100644 --- a/indra/plugins/filepicker/llfilepicker.h +++ b/indra/plugins/filepicker/llfilepicker.h @@ -60,10 +60,14 @@ public: FFLOAD_XML = 6, FFLOAD_SLOBJECT = 7, FFLOAD_RAW = 8, + FFLOAD_MODEL = 9, + FFLOAD_COLLADA = 10, + FFLOAD_SCRIPT = 11, + FFLOAD_DICTIONARY = 12, // - FFLOAD_INVGZ = 9, - FFLOAD_AO = 10, - FFLOAD_BLACKLIST = 11 + FFLOAD_INVGZ = 13, + FFLOAD_AO = 14, + FFLOAD_BLACKLIST = 15 // }; @@ -84,12 +88,12 @@ public: FFSAVE_J2C = 12, FFSAVE_PNG = 13, FFSAVE_JPEG = 14, + FFSAVE_SCRIPT = 15, // - FFSAVE_ANIMATN = 15, - FFSAVE_OGG = 16, - FFSAVE_NOTECARD = 17, - FFSAVE_GESTURE = 18, - FFSAVE_LSL = 19, + FFSAVE_ANIMATN = 16, + FFSAVE_OGG = 17, + FFSAVE_NOTECARD = 18, + FFSAVE_GESTURE = 19, // good grief FFSAVE_SHAPE = 20, FFSAVE_SKIN = 21,