From b28492fbffd7bea9e7174260d66d5f52c76d24b2 Mon Sep 17 00:00:00 2001 From: Ima Mechanique Date: Thu, 17 Nov 2011 23:17:26 +0000 Subject: STORM-1708 Adding ability to save/load scripts from file. --- indra/newview/llpreviewscript.cpp | 78 +++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 8 deletions(-) (limited to 'indra/newview/llpreviewscript.cpp') diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index b19bf5d234..072df39514 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -35,6 +35,7 @@ #include "llcombobox.h" #include "lldir.h" #include "llexternaleditor.h" +#include "llfilepicker.h" #include "llfloaterreg.h" #include "llinventorydefines.h" #include "llinventorymodel.h" @@ -89,15 +90,15 @@ const std::string HELLO_LSL = "default\n" "{\n" - " state_entry()\n" - " {\n" - " llSay(0, \"Hello, Avatar!\");\n" - " }\n" + "\tstate_entry()\n" + "\t{\n" + "\t\tllOwnerSay(\"Hello, Avatar!\");\n" + "\t}\n" "\n" - " touch_start(integer total_number)\n" - " {\n" - " llSay(0, \"Touched.\");\n" - " }\n" + "\ttouch_start(integer total_number)\n" + "\t{\n" + "\t\tllSay(llDetectedKey(0), \"Touched.\");\n" + "\t}\n" "}\n"; const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal"; @@ -503,6 +504,14 @@ void LLScriptEdCore::initMenu() menuItem = getChild("Keyword Help..."); menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this)); + + menuItem = getChild("LoadFromFile"); + menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnLoadFromFile, this)); +// menuItem->setEnabledCallback(NULL); + + menuItem = getChild("SaveToFile"); + menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnSaveToFile, this)); + menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::hasChanged, this)); } void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid) @@ -1096,6 +1105,59 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) return FALSE; } +void LLScriptEdCore::onBtnLoadFromFile( void* data ) +{ + + LLScriptEdCore* self = (LLScriptEdCore*) data; + + LLFilePicker& file_picker = LLFilePicker::instance(); + if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) ) + { + return; + } + + std::string filename = file_picker.getFirstFile(); + + std::ifstream fin(filename.c_str()); + + std::string line; + std::string linetotal; + self->mEditor->clear(); + while (!fin.eof()) + { + getline(fin,line); + line=line+"\n"; + self->mEditor->insertText(line); + + } + fin.close(); +} + +void LLScriptEdCore::onBtnSaveToFile( void* userdata ) +{ + + LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); + + LLScriptEdCore* self = (LLScriptEdCore*) userdata; + + if( self->mSaveCallback ) + { + LLFilePicker& file_picker = LLFilePicker::instance(); + if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) ) + { + return; + } + + std::string filename = file_picker.getFirstFile(); + std::string scriptText=self->mEditor->getText(); + std::ofstream fout(filename.c_str()); + fout<<(scriptText); + fout.close(); + self->mSaveCallback( self->mUserdata, FALSE ); + } +} + + /// --------------------------------------------------------------------------- /// LLScriptEdContainer /// --------------------------------------------------------------------------- -- cgit v1.3 From eeefec394c932b79a22c5ea2b8aa03690bb6061e Mon Sep 17 00:00:00 2001 From: Ima Mechanique Date: Wed, 23 Nov 2011 01:30:15 +0000 Subject: Changes to filter out tabs from file load and to test if loading/saving should be allowed. --- indra/llui/lltexteditor.cpp | 26 ++++++++++++++++++ indra/llui/lltexteditor.h | 5 ++++ indra/newview/llfilepicker.cpp | 12 +-------- indra/newview/llpreviewscript.cpp | 56 +++++++++++++++++++++++++++++++++------ indra/newview/llpreviewscript.h | 4 +++ 5 files changed, 84 insertions(+), 19 deletions(-) (limited to 'indra/newview/llpreviewscript.cpp') diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 9bd445988d..3a23ce1cac 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2250,6 +2250,22 @@ void LLTextEditor::insertText(const std::string &new_text) setEnabled( enabled ); } +void LLTextEditor::insertText(LLWString &new_text) +{ + BOOL enabled = getEnabled(); + setEnabled( TRUE ); + + // Delete any selected characters (the insertion replaces them) + if( hasSelection() ) + { + deleteSelection(TRUE); + } + + setCursorPos(mCursorPos + insert( mCursorPos, new_text, FALSE, LLTextSegmentPtr() )); + + setEnabled( enabled ); +} + void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo) { // Save old state @@ -2838,3 +2854,13 @@ void LLTextEditor::clear() getViewModel()->setDisplay(LLWStringUtil::null); clearSegments(); } + +bool LLTextEditor::canLoadOrSaveToFile() +{ + return !mReadOnly; +} + +S32 LLTextEditor::spacesPerTab() +{ + return SPACES_PER_TAB; +} diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 9e4b95003b..40821ae9fb 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -92,6 +92,8 @@ public: void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;} + static S32 spacesPerTab(); + // mousehandler overrides virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); @@ -140,6 +142,8 @@ public: virtual void selectAll(); virtual BOOL canSelectAll() const; + virtual bool canLoadOrSaveToFile(); + void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); @@ -158,6 +162,7 @@ public: // inserts text at cursor void insertText(const std::string &text); + void insertText(LLWString &text); void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo); // Non-undoable diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 0801871409..3cbc4e5648 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -58,7 +58,7 @@ LLFilePicker LLFilePicker::sInstance; #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; *.txt)\0*.lsl;*.txt\0" +#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" #endif // @@ -502,16 +502,6 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) L"Compressed Images (*.j2c)\0*.j2c\0" \ L"\0"; break; - case FFSAVE_SCRIPT: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"txt"; - mOFN.lpstrFilter = - L"LSL Files (*.lsl; *.txt)\0*.lsl;*.txt\0" - L"\0"; - break; default: return FALSE; } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 072df39514..16b582d188 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -507,11 +507,11 @@ void LLScriptEdCore::initMenu() menuItem = getChild("LoadFromFile"); menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnLoadFromFile, this)); -// menuItem->setEnabledCallback(NULL); + menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::enableLoadFromFileMenu, this)); menuItem = getChild("SaveToFile"); menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnSaveToFile, this)); - menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::hasChanged, this)); + menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::enableSaveToFileMenu, this)); } void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid) @@ -1107,9 +1107,17 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) void LLScriptEdCore::onBtnLoadFromFile( void* data ) { - LLScriptEdCore* self = (LLScriptEdCore*) data; - +/* + if( self->isDirty()) + { + llwarns << "Script has unsaved changes, loading from disc aborted." << llendl; + LLStringBase::format_map_t args; + args["[REASON]"] = std::string("Existing script has unsaved changes. You must save this script before loading from disc."); + gViewerWindow->alertXml("LoadDiskScriptFailReason", args); + return; + } +*/ LLFilePicker& file_picker = LLFilePicker::instance(); if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) ) { @@ -1121,16 +1129,27 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) std::ifstream fin(filename.c_str()); std::string line; + std::string text; std::string linetotal; - self->mEditor->clear(); while (!fin.eof()) { getline(fin,line); - line=line+"\n"; - self->mEditor->insertText(line); - + text += line; + if (!fin.eof()) + { + text += "\n"; + } } fin.close(); + + // Only replace the script if there is something to replace with. + if (text.length() > 0) + { + self->mEditor->selectAll(); + LLWString script(utf8str_to_wstring(text)); + LLWStringUtil::replaceTabsWithSpaces(script, self->mEditor->spacesPerTab()); + self->mEditor->insertText(script); + } } void LLScriptEdCore::onBtnSaveToFile( void* userdata ) @@ -1157,6 +1176,27 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata ) } } +bool LLScriptEdCore::canLoadOrSaveToFile( void* userdata ) +{ + LLScriptEdCore* self = (LLScriptEdCore*) userdata; + return self->mEditor->canLoadOrSaveToFile(); +} + +// static +bool LLScriptEdCore::enableSaveToFileMenu(void* userdata) +{ + LLScriptEdCore* self = (LLScriptEdCore*)userdata; + if (!self || !self->mEditor) return FALSE; + return self->mEditor->canLoadOrSaveToFile(); +} + +// static +bool LLScriptEdCore::enableLoadFromFileMenu(void* userdata) +{ + LLScriptEdCore* self = (LLScriptEdCore*)userdata; + if (!self || !self->mEditor) return FALSE; + return self->mEditor->canLoadOrSaveToFile(); +} /// --------------------------------------------------------------------------- /// LLScriptEdContainer diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index f50e9322b0..7563cecd9d 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -79,6 +79,7 @@ public: /*virtual*/ BOOL postBuild(); BOOL canClose(); void setEnableEditing(bool enable); + bool canLoadOrSaveToFile( void* userdata ); void setScriptText(const std::string& text, BOOL is_valid); bool loadScriptText(const std::string& filename); @@ -101,6 +102,9 @@ public: static void onBtnLoadFromFile(void*); static void onBtnSaveToFile(void*); + static bool enableSaveToFileMenu(void* userdata); + static bool enableLoadFromFileMenu(void* userdata); + virtual bool hasAccelerators() const { return true; } private: -- cgit v1.3 From 413cd15f070c6c0406026c96e0b70698120366ef Mon Sep 17 00:00:00 2001 From: Ima Mechanique Date: Thu, 24 Nov 2011 12:48:17 +0000 Subject: Fixed accidental change to HELLO_WORLD script. --- indra/newview/llpreviewscript.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indra/newview/llpreviewscript.cpp') diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 16b582d188..0a429269ba 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -90,15 +90,15 @@ const std::string HELLO_LSL = "default\n" "{\n" - "\tstate_entry()\n" - "\t{\n" - "\t\tllOwnerSay(\"Hello, Avatar!\");\n" - "\t}\n" + " state_entry()\n" + " {\n" + " llOwnerSay(\"Hello, Avatar!\");\n" + " }\n" "\n" - "\ttouch_start(integer total_number)\n" - "\t{\n" - "\t\tllSay(llDetectedKey(0), \"Touched.\");\n" - "\t}\n" + " touch_start(integer total_number)\n" + " {\n" + " llSay(llDetectedKey(0), \"Touched.\");\n" + " }\n" "}\n"; const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal"; -- cgit v1.3 From 468543c944b073af41a3cf7f6dfe73f097c2eb2d Mon Sep 17 00:00:00 2001 From: Ima Mechanique Date: Thu, 8 Dec 2011 10:33:23 +0000 Subject: Reverting the changes to default script which leaked in from another project ;-) --- indra/newview/llpreviewscript.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indra/newview/llpreviewscript.cpp') diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 0a429269ba..62603a2e07 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -90,15 +90,15 @@ const std::string HELLO_LSL = "default\n" "{\n" - " state_entry()\n" - " {\n" - " llOwnerSay(\"Hello, Avatar!\");\n" - " }\n" + " state_entry()\n" + " {\n" + " llSay(0, \"Hello, Avatar!\");\n" + " }\n" "\n" - " touch_start(integer total_number)\n" - " {\n" - " llSay(llDetectedKey(0), \"Touched.\");\n" - " }\n" + " touch_start(integer total_number)\n" + " {\n" + " llSay(0, \"Touched.\");\n" + " }\n" "}\n"; const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal"; -- cgit v1.3 From 04d5ba4ab982eed493502dca228134191acb78da Mon Sep 17 00:00:00 2001 From: Ima Mechanique Date: Fri, 9 Dec 2011 09:51:25 +0000 Subject: General cleanup of new code (removing commented lines, experimetal stuff), adding some comments per RB feedback. --- indra/newview/llpreviewscript.cpp | 15 ++------ indra/newview/skins/default/xui/en/strings.xml | 52 +++++++++++++------------- 2 files changed, 30 insertions(+), 37 deletions(-) (limited to 'indra/newview/llpreviewscript.cpp') diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 62603a2e07..cab30b1295 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1108,19 +1108,12 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) void LLScriptEdCore::onBtnLoadFromFile( void* data ) { LLScriptEdCore* self = (LLScriptEdCore*) data; -/* - if( self->isDirty()) - { - llwarns << "Script has unsaved changes, loading from disc aborted." << llendl; - LLStringBase::format_map_t args; - args["[REASON]"] = std::string("Existing script has unsaved changes. You must save this script before loading from disc."); - gViewerWindow->alertXml("LoadDiskScriptFailReason", args); - return; - } -*/ + + // TODO Maybe add a dialogue warning here if the current file has unsaved changes. LLFilePicker& file_picker = LLFilePicker::instance(); if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) ) { + //File picking cancelled by user, so nothing to do. return; } @@ -1147,7 +1140,6 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) { self->mEditor->selectAll(); LLWString script(utf8str_to_wstring(text)); - LLWStringUtil::replaceTabsWithSpaces(script, self->mEditor->spacesPerTab()); self->mEditor->insertText(script); } } @@ -1164,6 +1156,7 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata ) LLFilePicker& file_picker = LLFilePicker::instance(); if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) ) { + //File picking cancelled by user, so nothing to do. return; } diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0d26465dfa..f962ff0aee 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -88,7 +88,7 @@ We are very sorry for the inconvenience. Logins are currently restricted to employees only. Check www.secondlife.com/status for updates. Second Life logins are temporarily restricted in order to make sure that those in-world have the best possible experience. - + People with free accounts will not be able to access Second Life during this time, to make room for those who have paid for Second Life. Second Life cannot be accessed from this computer. If you feel this is an error, please contact @@ -168,7 +168,7 @@ Please try logging in again in a minute. You are wearing one or more of these objects. Remove them from your avatar and try moving them again. This folder has too many levels of subfolders. Rearrange the interior folders to a maximum of 4 levels deep (Root Folder contains A contains B contains C). This folder contains more than 200 objects. Box some of the items to reduce the object count. - + Click to view this web page Click to view this location's information @@ -188,7 +188,7 @@ Please try logging in again in a minute. Click to view this object's description Click to view this location on a map Click to run the secondlife:// command - + Teleport to @@ -427,7 +427,7 @@ Please try logging in again in a minute. Compressed Images Load Files Choose Directory - Scripts + Scripts Shirt not worn Pants not worn @@ -1988,7 +1988,7 @@ Returns a string with the requested data about the region New [WEARABLE_ITEM] - + Next @@ -2314,7 +2314,7 @@ Returns a string with the requested data about the region Error: script information is only available in your current region Retrieving information... You do not have permission to examine this parcel - + Sitting On Chest Head @@ -2354,7 +2354,7 @@ Returns a string with the requested data about the region HUD Bottom Left HUD Bottom HUD Bottom Right - + Line [LINE], Column [COLUMN] @@ -2367,7 +2367,7 @@ Returns a string with the requested data about the region Content of object - New Script + New Script The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing. @@ -2397,7 +2397,7 @@ Returns a string with the requested data about the region Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile (will update after publish) - + You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified. User has no picks or classifieds @@ -3274,7 +3274,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. You have blocked this Resident. Sending a message will automatically unblock them. @@ -3300,7 +3300,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. You are not a session moderator. @@ -3313,12 +3313,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Unable to add users to chat session with [RECIPIENT]. Unable to send your message to the chat session with [RECIPIENT]. - + Unable to send your message to the chat session with [RECIPIENT]. @@ -3326,7 +3326,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Error while moderating. @@ -3347,9 +3347,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. The session initialization is timed out - + Home position set. - + http://secondlife.com/landing/voicemorphing @@ -3367,20 +3367,20 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. to join a group to upload to publish a classified ad - + Giving L$ [AMOUNT] Uploading costs L$ [AMOUNT] This costs L$ [AMOUNT] Buying selected land for L$ [AMOUNT] This object costs L$ [AMOUNT] - + Everyone Officers Owners Online Uploading... - + Abuse Report @@ -3474,23 +3474,23 @@ Abuse Report [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] - + none/none Can't load images larger than [WIDTH]*[HEIGHT] - + Despite our best efforts, something unexpected has gone wrong. - Please check status.secondlifegrid.net to see if there is a known problem with the service. + Please check status.secondlifegrid.net to see if there is a known problem with the service. If you continue to experience problems, please check your network and firewall setup. - Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday Sun:Mon:Tue:Wed:Thu:Fri:Sat @@ -3523,7 +3523,7 @@ Abuse Report Delete selected item? There are no items in this outfit - + Select an editor using the ExternalEditor setting. Cannot find the external editor you specified. -- cgit v1.3 From ce6bd89ca4fbc3d1d75725e8cfc8857e21052107 Mon Sep 17 00:00:00 2001 From: Ima Mechanique Date: Wed, 4 Jan 2012 15:16:35 +0000 Subject: Changes per Oz's suggestion on RB. --- indra/newview/llpreviewscript.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'indra/newview/llpreviewscript.cpp') diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index cab30b1295..88727bf59b 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1154,18 +1154,15 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata ) if( self->mSaveCallback ) { LLFilePicker& file_picker = LLFilePicker::instance(); - if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) ) + if( file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) ) { - //File picking cancelled by user, so nothing to do. - return; + std::string filename = file_picker.getFirstFile(); + std::string scriptText=self->mEditor->getText(); + std::ofstream fout(filename.c_str()); + fout<<(scriptText); + fout.close(); + self->mSaveCallback( self->mUserdata, FALSE ); } - - std::string filename = file_picker.getFirstFile(); - std::string scriptText=self->mEditor->getText(); - std::ofstream fout(filename.c_str()); - fout<<(scriptText); - fout.close(); - self->mSaveCallback( self->mUserdata, FALSE ); } } @@ -1187,8 +1184,7 @@ bool LLScriptEdCore::enableSaveToFileMenu(void* userdata) bool LLScriptEdCore::enableLoadFromFileMenu(void* userdata) { LLScriptEdCore* self = (LLScriptEdCore*)userdata; - if (!self || !self->mEditor) return FALSE; - return self->mEditor->canLoadOrSaveToFile(); + return (self && self->mEditor) ? self->mEditor->canLoadOrSaveToFile() : FALSE; } /// --------------------------------------------------------------------------- -- cgit v1.3