mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 11:10:31 +03:00
ecode: add configurable screenshot support
Add an unlocked take-screenshot command and expose it under Settings -> Window with a default Print Screen binding. Allow configuring the screenshot destination, filename pattern, and output format. Save screenshots under the ecode configuration directory by default, notify users after capture, and provide an action to open the result in the integrated image viewer. Addresses a request in SpartanJ/ecode#950.
This commit is contained in:
@@ -930,4 +930,20 @@ Für sichtbare Änderung ecode neu starten.</string>
|
|||||||
<string name="zoom_in">Hereinzoomen</string>
|
<string name="zoom_in">Hereinzoomen</string>
|
||||||
<string name="zoom_out">Herauszoomen</string>
|
<string name="zoom_out">Herauszoomen</string>
|
||||||
<string name="zoom_reset">Zoom zurücksetzen</string>
|
<string name="zoom_reset">Zoom zurücksetzen</string>
|
||||||
|
<string name="take_screenshot">Bildschirmfoto aufnehmen</string>
|
||||||
|
<string name="screenshot_settings">Bildschirmfoto-Einstellungen</string>
|
||||||
|
<string name="screenshot_save_path">Speicherpfad</string>
|
||||||
|
<string name="screenshot_filename_pattern">Dateinamensmuster</string>
|
||||||
|
<string name="screenshot_save_format">Speicherformat</string>
|
||||||
|
<string name="set_screenshot_filename_pattern">Dateinamensmuster für Bildschirmfotos festlegen</string>
|
||||||
|
<string name="set_screenshot_filename_pattern_message">Legen Sie das Dateinamensmuster für Bildschirmfotos fest:
|
||||||
|
Verwendet strftime-Formatbezeichner. Die Dateierweiterung richtet sich nach dem ausgewählten Bildschirmfotoformat.</string>
|
||||||
|
<string name="set_screenshot_save_format">Speicherformat für Bildschirmfotos festlegen</string>
|
||||||
|
<string name="set_screenshot_save_format_message">Wählen Sie das Speicherformat für Bildschirmfotos:</string>
|
||||||
|
<string name="invalid_screenshot_filename_pattern">Das Dateinamensmuster für Bildschirmfotos ist ungültig.</string>
|
||||||
|
<string name="invalid_screenshot_save_format">Ungültiges Speicherformat für Bildschirmfotos.</string>
|
||||||
|
<string name="couldnt_create_screenshot_directory">Das Verzeichnis für Bildschirmfotos konnte nicht erstellt werden.</string>
|
||||||
|
<string name="couldnt_find_available_screenshot_filename">Es konnte kein verfügbarer Dateiname für das Bildschirmfoto gefunden werden.</string>
|
||||||
|
<string name="couldnt_save_screenshot">Das Bildschirmfoto konnte nicht gespeichert werden.</string>
|
||||||
|
<string name="screenshot_saved">Bildschirmfoto gespeichert:</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -914,4 +914,20 @@ Restart ecode to see the changes.</string>
|
|||||||
<string name="zoom_in">Zoom In</string>
|
<string name="zoom_in">Zoom In</string>
|
||||||
<string name="zoom_out">Zoom Out</string>
|
<string name="zoom_out">Zoom Out</string>
|
||||||
<string name="zoom_reset">Zoom Reset</string>
|
<string name="zoom_reset">Zoom Reset</string>
|
||||||
|
<string name="take_screenshot">Take Screenshot</string>
|
||||||
|
<string name="screenshot_settings">Screenshot Settings</string>
|
||||||
|
<string name="screenshot_save_path">Save Path</string>
|
||||||
|
<string name="screenshot_filename_pattern">Filename Pattern</string>
|
||||||
|
<string name="screenshot_save_format">Save Format</string>
|
||||||
|
<string name="set_screenshot_filename_pattern">Set Screenshot Filename Pattern</string>
|
||||||
|
<string name="set_screenshot_filename_pattern_message">Set the screenshot filename pattern:
|
||||||
|
Uses strftime format specifiers. The file extension follows the selected screenshot format.</string>
|
||||||
|
<string name="set_screenshot_save_format">Set Screenshot Save Format</string>
|
||||||
|
<string name="set_screenshot_save_format_message">Select the screenshot save format:</string>
|
||||||
|
<string name="invalid_screenshot_filename_pattern">The screenshot filename pattern is invalid.</string>
|
||||||
|
<string name="invalid_screenshot_save_format">Invalid screenshot save format.</string>
|
||||||
|
<string name="couldnt_create_screenshot_directory">Couldn't create the screenshot directory.</string>
|
||||||
|
<string name="couldnt_find_available_screenshot_filename">Couldn't find an available screenshot filename.</string>
|
||||||
|
<string name="couldnt_save_screenshot">Couldn't save the screenshot.</string>
|
||||||
|
<string name="screenshot_saved">Screenshot saved:</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -909,4 +909,20 @@ Redémarrer ecode pour voir les changements.</string>
|
|||||||
<string name="terminal_open_link">Ouvrir le lien</string>
|
<string name="terminal_open_link">Ouvrir le lien</string>
|
||||||
<string name="terminal_paste">Coller dans le terminal</string>
|
<string name="terminal_paste">Coller dans le terminal</string>
|
||||||
<string name="terminal_rename">Renommer le terminal</string>
|
<string name="terminal_rename">Renommer le terminal</string>
|
||||||
|
<string name="take_screenshot">Prendre une capture d’écran</string>
|
||||||
|
<string name="screenshot_settings">Paramètres des captures d’écran</string>
|
||||||
|
<string name="screenshot_save_path">Dossier d’enregistrement</string>
|
||||||
|
<string name="screenshot_filename_pattern">Modèle de nom de fichier</string>
|
||||||
|
<string name="screenshot_save_format">Format d’enregistrement</string>
|
||||||
|
<string name="set_screenshot_filename_pattern">Définir le modèle de nom des captures d’écran</string>
|
||||||
|
<string name="set_screenshot_filename_pattern_message">Définissez le modèle de nom des captures d’écran :
|
||||||
|
Utilise les spécificateurs de format strftime. L’extension du fichier correspond au format de capture sélectionné.</string>
|
||||||
|
<string name="set_screenshot_save_format">Définir le format des captures d’écran</string>
|
||||||
|
<string name="set_screenshot_save_format_message">Sélectionnez le format d’enregistrement des captures d’écran :</string>
|
||||||
|
<string name="invalid_screenshot_filename_pattern">Le modèle de nom des captures d’écran n’est pas valide.</string>
|
||||||
|
<string name="invalid_screenshot_save_format">Le format d’enregistrement des captures d’écran n’est pas valide.</string>
|
||||||
|
<string name="couldnt_create_screenshot_directory">Impossible de créer le dossier des captures d’écran.</string>
|
||||||
|
<string name="couldnt_find_available_screenshot_filename">Impossible de trouver un nom de fichier disponible pour la capture d’écran.</string>
|
||||||
|
<string name="couldnt_save_screenshot">Impossible d’enregistrer la capture d’écran.</string>
|
||||||
|
<string name="screenshot_saved">Capture d’écran enregistrée :</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -688,4 +688,20 @@ file in the directory tree.</string>
|
|||||||
<string name="zoom_in">字小</string>
|
<string name="zoom_in">字小</string>
|
||||||
<string name="zoom_out">字大</string>
|
<string name="zoom_out">字大</string>
|
||||||
<string name="zoom_reset">重设字体大小</string>
|
<string name="zoom_reset">重设字体大小</string>
|
||||||
|
<string name="take_screenshot">截取屏幕截图</string>
|
||||||
|
<string name="screenshot_settings">屏幕截图设置</string>
|
||||||
|
<string name="screenshot_save_path">保存路径</string>
|
||||||
|
<string name="screenshot_filename_pattern">文件名格式</string>
|
||||||
|
<string name="screenshot_save_format">保存格式</string>
|
||||||
|
<string name="set_screenshot_filename_pattern">设置屏幕截图文件名格式</string>
|
||||||
|
<string name="set_screenshot_filename_pattern_message">设置屏幕截图文件名格式:
|
||||||
|
使用 strftime 格式说明符。文件扩展名由所选屏幕截图格式决定。</string>
|
||||||
|
<string name="set_screenshot_save_format">设置屏幕截图保存格式</string>
|
||||||
|
<string name="set_screenshot_save_format_message">选择屏幕截图保存格式:</string>
|
||||||
|
<string name="invalid_screenshot_filename_pattern">屏幕截图文件名格式无效。</string>
|
||||||
|
<string name="invalid_screenshot_save_format">屏幕截图保存格式无效。</string>
|
||||||
|
<string name="couldnt_create_screenshot_directory">无法创建屏幕截图目录。</string>
|
||||||
|
<string name="couldnt_find_available_screenshot_filename">无法找到可用的屏幕截图文件名。</string>
|
||||||
|
<string name="couldnt_save_screenshot">无法保存屏幕截图。</string>
|
||||||
|
<string name="screenshot_saved">屏幕截图已保存:</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -127,6 +127,12 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
|
|||||||
windowState.lastRunVersion = iniState.getValueU( "editor", "last_run_version", 0 );
|
windowState.lastRunVersion = iniState.getValueU( "editor", "last_run_version", 0 );
|
||||||
windowState.sidePanelTabsOrder =
|
windowState.sidePanelTabsOrder =
|
||||||
String::split( iniState.getValue( "ui", "side_panel_tabs_order", "" ), ',' );
|
String::split( iniState.getValue( "ui", "side_panel_tabs_order", "" ), ',' );
|
||||||
|
screenshot.savePath = ini.getValue( "screenshots", "save_path", "" );
|
||||||
|
screenshot.filenamePattern =
|
||||||
|
ini.getValue( "screenshots", "filename_pattern", "ecode-%Y-%m-%d-%H-%M-%S.png" );
|
||||||
|
screenshot.saveFormat = ini.getValue( "screenshots", "save_format", "png" );
|
||||||
|
if ( Image::extensionToSaveType( screenshot.saveFormat ) == Image::SaveType::Unknown )
|
||||||
|
screenshot.saveFormat = "png";
|
||||||
editor.showLineNumbers = ini.getValueB( "editor", "show_line_numbers", true );
|
editor.showLineNumbers = ini.getValueB( "editor", "show_line_numbers", true );
|
||||||
editor.showWhiteSpaces = ini.getValueB( "editor", "show_white_spaces", true );
|
editor.showWhiteSpaces = ini.getValueB( "editor", "show_white_spaces", true );
|
||||||
editor.showLineEndings = ini.getValueB( "editor", "show_line_endings", false );
|
editor.showLineEndings = ini.getValueB( "editor", "show_line_endings", false );
|
||||||
@@ -366,6 +372,9 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
|
|||||||
ini.setValue( "ui", "font_hinting", FontTrueType::fontHintingToString( ui.fontHinting ) );
|
ini.setValue( "ui", "font_hinting", FontTrueType::fontHintingToString( ui.fontHinting ) );
|
||||||
ini.setValue( "ui", "font_antialiasing",
|
ini.setValue( "ui", "font_antialiasing",
|
||||||
FontTrueType::fontAntialiasingToString( ui.fontAntialiasing ) );
|
FontTrueType::fontAntialiasingToString( ui.fontAntialiasing ) );
|
||||||
|
ini.setValue( "screenshots", "save_path", screenshot.savePath );
|
||||||
|
ini.setValue( "screenshots", "filename_pattern", screenshot.filenamePattern );
|
||||||
|
ini.setValue( "screenshots", "save_format", screenshot.saveFormat );
|
||||||
ini.setValueB( "ui", "editor_font_in_input_fields", ui.editorFontInInputFields );
|
ini.setValueB( "ui", "editor_font_in_input_fields", ui.editorFontInInputFields );
|
||||||
iniState.setValue( "ui", "side_panel_tabs_order",
|
iniState.setValue( "ui", "side_panel_tabs_order",
|
||||||
String::join( windowState.sidePanelTabsOrder, ',' ) );
|
String::join( windowState.sidePanelTabsOrder, ',' ) );
|
||||||
|
|||||||
@@ -96,6 +96,12 @@ struct WindowStateConfig {
|
|||||||
std::vector<std::string> sidePanelTabsOrder;
|
std::vector<std::string> sidePanelTabsOrder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScreenshotConfig {
|
||||||
|
std::string savePath;
|
||||||
|
std::string filenamePattern{ "ecode-%Y-%m-%d-%H-%M-%S.png" };
|
||||||
|
std::string saveFormat{ "png" };
|
||||||
|
};
|
||||||
|
|
||||||
struct CodeEditorConfig {
|
struct CodeEditorConfig {
|
||||||
std::string colorScheme{ "ecode" };
|
std::string colorScheme{ "ecode" };
|
||||||
StyleSheetLength fontSize{ 11, StyleSheetLength::Dp };
|
StyleSheetLength fontSize{ 11, StyleSheetLength::Dp };
|
||||||
@@ -296,6 +302,7 @@ struct TabWidgetCbs {
|
|||||||
class AppConfig {
|
class AppConfig {
|
||||||
public:
|
public:
|
||||||
WindowStateConfig windowState;
|
WindowStateConfig windowState;
|
||||||
|
ScreenshotConfig screenshot;
|
||||||
ContextSettings context;
|
ContextSettings context;
|
||||||
CodeEditorConfig editor;
|
CodeEditorConfig editor;
|
||||||
DocumentConfig doc;
|
DocumentConfig doc;
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ class DateTimeController {
|
|||||||
|
|
||||||
void registerCommands( TextDocument& doc );
|
void registerCommands( TextDocument& doc );
|
||||||
|
|
||||||
private:
|
|
||||||
PluginContextProvider* mContext{ nullptr };
|
|
||||||
|
|
||||||
static bool isValidDateFormat( const std::string& format );
|
static bool isValidDateFormat( const std::string& format );
|
||||||
|
|
||||||
static std::string formatCurrentDate( const std::string& format );
|
static std::string formatCurrentDate( const std::string& format );
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginContextProvider* mContext{ nullptr };
|
||||||
|
|
||||||
void insertDate( const std::string& format );
|
void insertDate( const std::string& format );
|
||||||
|
|
||||||
void setCustomDateFormat();
|
void setCustomDateFormat();
|
||||||
|
|||||||
@@ -392,6 +392,14 @@ std::string App::getDefaultFileDialogFolder() const {
|
|||||||
return mLastFileFolder.empty() ? getLastUsedFolder() : mLastFileFolder;
|
return mLastFileFolder.empty() ? getLastUsedFolder() : mLastFileFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string App::getDefaultScreenshotPath() const {
|
||||||
|
std::string path( mConfigPath );
|
||||||
|
FileSystem::dirAddSlashAtEnd( path );
|
||||||
|
path += "screenshots";
|
||||||
|
FileSystem::dirAddSlashAtEnd( path );
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
std::string App::getLastUsedFolder() const {
|
std::string App::getLastUsedFolder() const {
|
||||||
if ( !mCurrentProject.empty() && mCurrentProject != getPlaygroundPath() )
|
if ( !mCurrentProject.empty() && mCurrentProject != getPlaygroundPath() )
|
||||||
return mCurrentProject;
|
return mCurrentProject;
|
||||||
@@ -2101,6 +2109,7 @@ static Uint32 DefaultSwitchToStatusPanelModifier = KEYMOD_LALT;
|
|||||||
|
|
||||||
std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
|
std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
|
||||||
return {
|
return {
|
||||||
|
{ { KEY_PRINTSCREEN, KEYMOD_NONE }, "take-screenshot" },
|
||||||
{ { KEY_RETURN, KEYMOD_LALT | KEYMOD_LCTRL }, "fullscreen-toggle" },
|
{ { KEY_RETURN, KEYMOD_LALT | KEYMOD_LCTRL }, "fullscreen-toggle" },
|
||||||
{ { KEY_F3, KEYMOD_NONE }, "repeat-find" },
|
{ { KEY_F3, KEYMOD_NONE }, "repeat-find" },
|
||||||
{ { KEY_F3, KEYMOD_SHIFT }, "find-prev" },
|
{ { KEY_F3, KEYMOD_SHIFT }, "find-prev" },
|
||||||
@@ -2167,6 +2176,10 @@ std::map<std::string, std::string> App::getMigrateKeybindings() {
|
|||||||
|
|
||||||
std::vector<std::string> App::getUnlockedCommands() {
|
std::vector<std::string> App::getUnlockedCommands() {
|
||||||
return {
|
return {
|
||||||
|
"take-screenshot",
|
||||||
|
"screenshot-save-path",
|
||||||
|
"screenshot-filename-pattern",
|
||||||
|
"screenshot-save-format",
|
||||||
"create-new",
|
"create-new",
|
||||||
"create-new-terminal",
|
"create-new-terminal",
|
||||||
"create-new-welcome-tab",
|
"create-new-welcome-tab",
|
||||||
@@ -2852,6 +2865,61 @@ void App::fullscreenToggle() {
|
|||||||
mSettings->updateViewMenu();
|
mSettings->updateViewMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::takeScreenshot() {
|
||||||
|
auto format = Image::extensionToSaveType( mConfig.screenshot.saveFormat );
|
||||||
|
if ( format == Image::SaveType::Unknown )
|
||||||
|
format = Image::SaveType::PNG;
|
||||||
|
|
||||||
|
std::string filename =
|
||||||
|
DateTimeController::formatCurrentDate( mConfig.screenshot.filenamePattern );
|
||||||
|
if ( filename.empty() ) {
|
||||||
|
errorMsgBox( i18n( "invalid_screenshot_filename_pattern",
|
||||||
|
"The screenshot filename pattern is invalid." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string extension = "." + Image::saveTypeToExtension( format );
|
||||||
|
const std::string configuredExtension = FileSystem::fileExtension( filename );
|
||||||
|
if ( !configuredExtension.empty() )
|
||||||
|
filename.resize( filename.size() - configuredExtension.size() - 1 );
|
||||||
|
filename += extension;
|
||||||
|
|
||||||
|
std::string savePath = mConfig.screenshot.savePath.empty() ? getDefaultScreenshotPath()
|
||||||
|
: mConfig.screenshot.savePath;
|
||||||
|
FileSystem::dirAddSlashAtEnd( savePath );
|
||||||
|
if ( !FileSystem::isDirectory( savePath ) && !FileSystem::makeDir( savePath, true ) ) {
|
||||||
|
errorMsgBox( i18n( "couldnt_create_screenshot_directory",
|
||||||
|
"Couldn't create the screenshot directory." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string filepath = savePath + filename;
|
||||||
|
if ( FileSystem::fileExists( filepath ) ) {
|
||||||
|
const std::string stem = FileSystem::fileRemoveExtension( filename );
|
||||||
|
bool availablePathFound = false;
|
||||||
|
for ( Uint32 suffix = 2; suffix < 10000; ++suffix ) {
|
||||||
|
filepath = savePath + stem + "-" + String::toString( suffix ) + extension;
|
||||||
|
if ( !FileSystem::fileExists( filepath ) ) {
|
||||||
|
availablePathFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !availablePathFound ) {
|
||||||
|
errorMsgBox( i18n( "couldnt_find_available_screenshot_filename",
|
||||||
|
"Couldn't find an available screenshot filename." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mWindow->takeScreenshot( filepath, format ) ) {
|
||||||
|
mNotificationCenter->addInteractiveNotification(
|
||||||
|
i18n( "screenshot_saved", "Screenshot saved:" ) + "\n" + filepath,
|
||||||
|
i18n( "open", "Open" ), [this, filepath] { openFileFromPath( filepath ); } );
|
||||||
|
} else {
|
||||||
|
errorMsgBox( i18n( "couldnt_save_screenshot", "Couldn't save the screenshot." ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void App::showGlobalSearch( bool searchAndReplace, std::optional<std::string> pathFilters ) {
|
void App::showGlobalSearch( bool searchAndReplace, std::optional<std::string> pathFilters ) {
|
||||||
mGlobalSearchController->showGlobalSearch( searchAndReplace, pathFilters );
|
mGlobalSearchController->showGlobalSearch( searchAndReplace, pathFilters );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider {
|
|||||||
|
|
||||||
std::string getDefaultFileDialogFolder() const;
|
std::string getDefaultFileDialogFolder() const;
|
||||||
|
|
||||||
|
std::string getDefaultScreenshotPath() const;
|
||||||
|
|
||||||
void openFolderDialog();
|
void openFolderDialog();
|
||||||
|
|
||||||
void openFontDialog( std::string& fontPath, bool loadingMonoFont, bool terminalFont = false,
|
void openFontDialog( std::string& fontPath, bool loadingMonoFont, bool terminalFont = false,
|
||||||
@@ -131,6 +133,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider {
|
|||||||
|
|
||||||
void fullscreenToggle();
|
void fullscreenToggle();
|
||||||
|
|
||||||
|
void takeScreenshot();
|
||||||
|
|
||||||
void downloadFileWebDialog();
|
void downloadFileWebDialog();
|
||||||
|
|
||||||
void showGlobalSearch( bool searchAndReplace, std::optional<std::string> pathFilters = {} );
|
void showGlobalSearch( bool searchAndReplace, std::optional<std::string> pathFilters = {} );
|
||||||
@@ -342,6 +346,13 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider {
|
|||||||
t.setCommand( "about-ecode", [this] { mSettingsActions->aboutEcode(); } );
|
t.setCommand( "about-ecode", [this] { mSettingsActions->aboutEcode(); } );
|
||||||
t.setCommand( "ecode-source", [this] { mSettingsActions->ecodeSource(); } );
|
t.setCommand( "ecode-source", [this] { mSettingsActions->ecodeSource(); } );
|
||||||
t.setCommand( "ui-scale-factor", [this] { mSettingsActions->setUIScaleFactor(); } );
|
t.setCommand( "ui-scale-factor", [this] { mSettingsActions->setUIScaleFactor(); } );
|
||||||
|
t.setCommand( "take-screenshot", [this] { takeScreenshot(); } );
|
||||||
|
t.setCommand( "screenshot-save-path",
|
||||||
|
[this] { mSettingsActions->setScreenshotSavePath(); } );
|
||||||
|
t.setCommand( "screenshot-filename-pattern",
|
||||||
|
[this] { mSettingsActions->setScreenshotFilenamePattern(); } );
|
||||||
|
t.setCommand( "screenshot-save-format",
|
||||||
|
[this] { mSettingsActions->setScreenshotSaveFormat(); } );
|
||||||
t.setCommand( "show-side-panel", [this] { switchSidePanel(); } );
|
t.setCommand( "show-side-panel", [this] { switchSidePanel(); } );
|
||||||
t.setCommand( "toggle-status-bar", [this] { switchStatusBar(); } );
|
t.setCommand( "toggle-status-bar", [this] { switchStatusBar(); } );
|
||||||
t.setCommand( "toggle-menu-bar", [this] { switchMenuBar(); } );
|
t.setCommand( "toggle-menu-bar", [this] { switchMenuBar(); } );
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void NotificationCenter::addShowRequest( const String& uri, const String& action
|
|||||||
auto action = [this, uri, actionText, delay]() {
|
auto action = [this, uri, actionText, delay]() {
|
||||||
static const auto layout = R"xml(
|
static const auto layout = R"xml(
|
||||||
<vbox lw="mp" class="notification">
|
<vbox lw="mp" class="notification">
|
||||||
<TextView lw="mp" wordwrap="true" />
|
<TextView lw="mp" lh="wc" word-wrap="true" />
|
||||||
<hbox lg="right">
|
<hbox lg="right">
|
||||||
<PushButton />
|
<PushButton />
|
||||||
</hbox>
|
</hbox>
|
||||||
@@ -103,7 +103,7 @@ void NotificationCenter::addInteractiveNotification( String text, String actionT
|
|||||||
allowCopy, onInteraction = std::move( onInteraction )]() {
|
allowCopy, onInteraction = std::move( onInteraction )]() {
|
||||||
static const auto layout = R"xml(
|
static const auto layout = R"xml(
|
||||||
<vbox lw="mp" class="notification">
|
<vbox lw="mp" class="notification">
|
||||||
<TextView lw="mp" wordwrap="true" />
|
<TextView lw="mp" lh="wc" word-wrap="true" />
|
||||||
<hbox lg="right">
|
<hbox lg="right">
|
||||||
<PushButton />
|
<PushButton />
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "settingsactions.hpp"
|
#include "settingsactions.hpp"
|
||||||
|
#include "datetimecontroller.hpp"
|
||||||
#include "ecode.hpp"
|
#include "ecode.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
@@ -414,6 +415,84 @@ void SettingsActions::setUIPanelFontSize() {
|
|||||||
mApp->setFocusEditorOnClose( msgBox );
|
mApp->setFocusEditorOnClose( msgBox );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsActions::setScreenshotSavePath() {
|
||||||
|
std::string initialPath = mApp->getConfig().screenshot.savePath;
|
||||||
|
if ( !FileSystem::isDirectory( initialPath ) ) {
|
||||||
|
initialPath = mApp->getDefaultScreenshotPath();
|
||||||
|
FileSystem::makeDir( initialPath, true );
|
||||||
|
}
|
||||||
|
UIFileDialog* dialog = UIFileDialog::New(
|
||||||
|
UIFileDialog::DefaultFlags | UIFileDialog::AllowFolderSelect |
|
||||||
|
UIFileDialog::ShowOnlyFolders |
|
||||||
|
( mApp->getConfig().ui.nativeFileDialogs ? UIFileDialog::UseNativeFileDialog : 0 ),
|
||||||
|
"*", initialPath );
|
||||||
|
dialog->setWindowFlags( UI_WIN_DEFAULT_FLAGS | UI_WIN_MAXIMIZE_BUTTON | UI_WIN_MODAL );
|
||||||
|
dialog->setTitle( i18n( "screenshot_save_path", "Screenshot Save Path" ) );
|
||||||
|
dialog->setCloseShortcut( KEY_ESCAPE );
|
||||||
|
dialog->on( Event::OpenFile, [this]( const Event* event ) {
|
||||||
|
std::string path = event->getNode()->asType<UIFileDialog>()->getFullPath();
|
||||||
|
if ( FileSystem::isDirectory( path ) ) {
|
||||||
|
FileSystem::dirAddSlashAtEnd( path );
|
||||||
|
mApp->getConfig().screenshot.savePath = std::move( path );
|
||||||
|
mApp->saveConfig();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
dialog->center();
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsActions::setScreenshotFilenamePattern() {
|
||||||
|
UIMessageBox* msgBox = UIMessageBox::New(
|
||||||
|
UIMessageBox::INPUT,
|
||||||
|
i18n( "set_screenshot_filename_pattern_message",
|
||||||
|
"Set the screenshot filename pattern:\nUses strftime format specifiers. The file "
|
||||||
|
"extension follows the selected screenshot format." ) );
|
||||||
|
msgBox->setTitle(
|
||||||
|
i18n( "set_screenshot_filename_pattern", "Set Screenshot Filename Pattern" ) );
|
||||||
|
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||||
|
msgBox->getTextInput()->setText( mApp->getConfig().screenshot.filenamePattern );
|
||||||
|
msgBox->showWhenReady();
|
||||||
|
msgBox->on( Event::OnConfirm, [this, msgBox]( const Event* ) {
|
||||||
|
std::string pattern = msgBox->getTextInput()->getText().toUtf8();
|
||||||
|
std::string filename = DateTimeController::formatCurrentDate( pattern );
|
||||||
|
if ( !DateTimeController::isValidDateFormat( pattern ) || filename.empty() ||
|
||||||
|
filename.find_first_of( "<>:\"/\\|?*" ) != std::string::npos ) {
|
||||||
|
msgBox->getTextInput()->addClass( "error" );
|
||||||
|
mApp->errorMsgBox( i18n( "invalid_screenshot_filename_pattern",
|
||||||
|
"The screenshot filename pattern is invalid." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mApp->getConfig().screenshot.filenamePattern = std::move( pattern );
|
||||||
|
mApp->saveConfig();
|
||||||
|
msgBox->closeWindow();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsActions::setScreenshotSaveFormat() {
|
||||||
|
UIMessageBox* msgBox = UIMessageBox::New(
|
||||||
|
UIMessageBox::DROPDOWNLIST,
|
||||||
|
i18n( "set_screenshot_save_format_message", "Select the screenshot save format:" ) );
|
||||||
|
msgBox->setTitle( i18n( "set_screenshot_save_format", "Set Screenshot Save Format" ) );
|
||||||
|
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||||
|
msgBox->getDropDownList()->getListBox()->addListBoxItems(
|
||||||
|
{ "PNG", "JPG", "WEBP", "QOI", "BMP", "TGA", "DDS" } );
|
||||||
|
msgBox->getDropDownList()->getListBox()->setSelected(
|
||||||
|
String( mApp->getConfig().screenshot.saveFormat ).toUpper() );
|
||||||
|
msgBox->showWhenReady();
|
||||||
|
msgBox->on( Event::OnConfirm, [this, msgBox]( const Event* ) {
|
||||||
|
String formatText( msgBox->getDropDownList()->getText() );
|
||||||
|
std::string format = formatText.toLower().toUtf8();
|
||||||
|
if ( Image::extensionToSaveType( format ) == Image::SaveType::Unknown ) {
|
||||||
|
mApp->errorMsgBox(
|
||||||
|
i18n( "invalid_screenshot_save_format", "Invalid screenshot save format." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mApp->getConfig().screenshot.saveFormat = std::move( format );
|
||||||
|
mApp->saveConfig();
|
||||||
|
msgBox->closeWindow();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
String SettingsActions::i18n( const std::string& key, const String& def ) {
|
String SettingsActions::i18n( const std::string& key, const String& def ) {
|
||||||
return mApp->i18n( key, def );
|
return mApp->i18n( key, def );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ class SettingsActions {
|
|||||||
|
|
||||||
void setUIPanelFontSize();
|
void setUIPanelFontSize();
|
||||||
|
|
||||||
|
void setScreenshotSavePath();
|
||||||
|
|
||||||
|
void setScreenshotFilenamePattern();
|
||||||
|
|
||||||
|
void setScreenshotSaveFormat();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
App* mApp{ nullptr };
|
App* mApp{ nullptr };
|
||||||
|
|
||||||
|
|||||||
@@ -1732,13 +1732,33 @@ UIMenu* SettingsMenu::createWindowMenu() {
|
|||||||
"to choose a language again when opening these files." ) )
|
"to choose a language again when opening these files." ) )
|
||||||
->setId( "reset-global-file-associations" );
|
->setId( "reset-global-file-associations" );
|
||||||
|
|
||||||
mWindowMenu->addSeparator();
|
|
||||||
|
|
||||||
mWindowMenu
|
mWindowMenu
|
||||||
->addCheckBox( i18n( "welcome_screen_enable", "Enable Welcome Screen" ),
|
->addCheckBox( i18n( "welcome_screen_enable", "Enable Welcome Screen" ),
|
||||||
mApp->getConfig().ui.welcomeScreen )
|
mApp->getConfig().ui.welcomeScreen )
|
||||||
->setId( "welcome-screen-enable" );
|
->setId( "welcome-screen-enable" );
|
||||||
|
|
||||||
|
mWindowMenu->addSeparator();
|
||||||
|
|
||||||
|
UIPopUpMenu* screenshotMenu = UIPopUpMenu::New();
|
||||||
|
screenshotMenu->add( i18n( "screenshot_save_path", "Save Path" ) )
|
||||||
|
->setId( "screenshot-save-path" );
|
||||||
|
screenshotMenu->add( i18n( "screenshot_filename_pattern", "Filename Pattern" ) )
|
||||||
|
->setId( "screenshot-filename-pattern" );
|
||||||
|
screenshotMenu->add( i18n( "screenshot_save_format", "Save Format" ) )
|
||||||
|
->setId( "screenshot-save-format" );
|
||||||
|
screenshotMenu->on( Event::OnItemClicked, [this]( const Event* event ) {
|
||||||
|
if ( event->getNode()->isType( UI_TYPE_MENUITEM ) )
|
||||||
|
runCommand( event->getNode()->getId() );
|
||||||
|
} );
|
||||||
|
mWindowMenu->addSubMenu( i18n( "screenshot_settings", "Screenshot Settings" ),
|
||||||
|
findIcon( "image" ), screenshotMenu );
|
||||||
|
|
||||||
|
mWindowMenu->addSeparator();
|
||||||
|
mWindowMenu
|
||||||
|
->add( i18n( "take_screenshot", "Take Screenshot" ), findIcon( "image" ),
|
||||||
|
getKeybind( "take-screenshot" ) )
|
||||||
|
->setId( "take-screenshot" );
|
||||||
|
|
||||||
mWindowMenu->on( Event::OnItemClicked, [this]( const Event* event ) {
|
mWindowMenu->on( Event::OnItemClicked, [this]( const Event* event ) {
|
||||||
if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) )
|
if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) )
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user