365 lines
10 KiB
C++
365 lines
10 KiB
C++
/*
|
|
* This file is part of the Colobot: Gold Edition source code
|
|
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
|
*
|
|
* 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 3 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 http://gnu.org/licenses
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "common/event.h"
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
|
|
struct Event;
|
|
|
|
namespace Ui
|
|
{
|
|
|
|
class CEdit;
|
|
class CInterface;
|
|
|
|
|
|
/**
|
|
* \brief File selector dialog
|
|
*
|
|
* \section Example Example usage
|
|
* Create the dialog and set the type of dialog.
|
|
* \code
|
|
* CFileDialog* fileDialog = new CFileDialog();
|
|
* fileDialog->SetDialogType(CFileDialog::Type::Folder);
|
|
* \endcode
|
|
*
|
|
* Initial settings and start the dialog.
|
|
* \code
|
|
* fileDialog->SetWindowTitle("Select Player Folder");
|
|
* fileDialog->SetBasePath("savegame");
|
|
* fileDialog->StartDialog();
|
|
* \endcode
|
|
*
|
|
* Handle events for the dialog.
|
|
* \code
|
|
* // first check for events sent from the dialog
|
|
*
|
|
* if (event.type == EVENT_DIALOG_STOP) // cancel or close
|
|
* {
|
|
* fileDialog->StopDialog();
|
|
* delete fileDialog;
|
|
* return true;
|
|
* }
|
|
*
|
|
* if (event.type == EVENT_DIALOG_ACTION) // ok button was pressed
|
|
* {
|
|
* std::string folder = fileDialog->GetSubFolderPath();
|
|
* fileDialog->StopDialog();
|
|
* delete fileDialog;
|
|
* return true;
|
|
* }
|
|
*
|
|
* // send the event to the dialog
|
|
* return m_fileDialog->EventProcess(event);
|
|
* \endcode
|
|
*
|
|
* \nosubgrouping
|
|
*/
|
|
class CFileDialog
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* \brief Constructor
|
|
*/
|
|
CFileDialog();
|
|
|
|
/**
|
|
* \brief Destructor
|
|
*/
|
|
~CFileDialog();
|
|
|
|
//! \name Set dialog type, starting, event processing, and stopping
|
|
//@{
|
|
/**
|
|
* \brief Disables other windows and creates the dialog window.
|
|
*/
|
|
void StartDialog();
|
|
|
|
/**
|
|
* \brief Enables other windows and deletes the dialog window.
|
|
*/
|
|
void StopDialog();
|
|
|
|
/**
|
|
* \brief Event processing.
|
|
*/
|
|
bool EventProcess(const Event &event);
|
|
|
|
/**
|
|
* \brief Identifies the type of dialog to display.
|
|
*/
|
|
enum class Type
|
|
{
|
|
None, //!< Type was not set
|
|
Open, //!< Open dialog
|
|
Save, //!< Save dialog
|
|
Folder, //!< Select Folder dialog
|
|
};
|
|
|
|
/**
|
|
* \brief Set the type of dialog to use.
|
|
*/
|
|
void SetDialogType(CFileDialog::Type type) { m_dialogtype = type; }
|
|
|
|
/**
|
|
* \brief Get the type of dialog.
|
|
*/
|
|
CFileDialog::Type GetDialogType() { return m_dialogtype; }
|
|
|
|
//@}
|
|
|
|
//! \name Dialog window properties
|
|
//@{
|
|
/**
|
|
* \brief Set EventType for the dialog window.
|
|
* If not set, a unique EventType will be used.
|
|
*/
|
|
void SetWindowEvent(EventType type) { m_windowEvent = type; }
|
|
|
|
/**
|
|
* \brief Get EventType for the dialog window.
|
|
*/
|
|
EventType GetWindowEvent() { return m_windowEvent; }
|
|
|
|
/**
|
|
* \brief Set the initial position of the window.
|
|
*/
|
|
void SetWindowPos(const glm::vec2& pos) { m_windowPos = pos; }
|
|
|
|
/**
|
|
* \brief Get the position of the window.
|
|
*/
|
|
glm::vec2 GetWindowPos() { return m_windowPos; }
|
|
|
|
/**
|
|
* \brief Set the initial size of the window.
|
|
*/
|
|
void SetWindowDim(const glm::vec2& dim) { m_windowDim = dim; }
|
|
|
|
/**
|
|
* \brief Get the size of the window.
|
|
*/
|
|
glm::vec2 GetWindowDim() { return m_windowDim; }
|
|
|
|
/**
|
|
* \brief Set the text for the title bar of the dialog.
|
|
* This setting will override the default title text for the dialog.
|
|
*/
|
|
void SetWindowTitle(const std::string& name) { m_title = name; }
|
|
|
|
//@}
|
|
|
|
//! \name Settings for Public and Private check boxes
|
|
//@{
|
|
/**
|
|
* \brief Set whether to create Public and Private check boxes.
|
|
* \param usePublic If true, Public and Private check boxes will be added to the dialog.
|
|
*/
|
|
void SetUsePublicPrivate(bool usePublic);
|
|
|
|
/**
|
|
* \brief Set initial state for Public and Private check boxes.
|
|
* \param bPublic If true, the Public check box will be marked.
|
|
*/
|
|
void SetPublic(bool bPublic);
|
|
|
|
/**
|
|
* \brief Get the state of Public and Private check boxes.
|
|
* \return true if Public check box is marked and false for Private.
|
|
*/
|
|
bool GetPublic();
|
|
|
|
/**
|
|
* \brief Set the path for the folder associated with the Public check box.
|
|
* \param dir Path to 'Public' folder.
|
|
*/
|
|
void SetPublicFolder(const std::string& dir);
|
|
|
|
/**
|
|
* \brief Set the path for the folder associated with the Private check box.
|
|
* \param dir Path to 'Private' folder.
|
|
*/
|
|
void SetPrivateFolder(const std::string& dir);
|
|
|
|
//@}
|
|
|
|
//! \name Folder settings
|
|
//@{
|
|
/**
|
|
* \brief Set the initial path for the folder whose contents are displayed.
|
|
* This setting is overridden by Public/Private settings.
|
|
*/
|
|
void SetBasePath(const std::string& dir);
|
|
|
|
/**
|
|
* \brief Get the initial path or Public/Private folder path
|
|
*/
|
|
std::string GetBasePath();
|
|
|
|
/**
|
|
* \brief Set the initial subfolder whose contents are displayed.
|
|
* \param dir Name of a subfolder. Ex. "subfolder/anotherFolder/oneMoreFolder"
|
|
*/
|
|
void SetSubFolderPath(const std::string& dir);
|
|
|
|
/**
|
|
* \brief Get the current subfolder shown by the dialog.
|
|
* \return A string with a folder name and subsequent folders separated by forward slash.
|
|
* <p>Returns empty string if the dialog is showing GetBasePath().
|
|
*/
|
|
std::string GetSubFolderPath();
|
|
|
|
//@}
|
|
|
|
//! \name File name settings
|
|
//@{
|
|
/**
|
|
* \brief Set the extension that may be appended to a file name.
|
|
* <p> If any extensions are defined, the dialog will only show files
|
|
* with those extensions.
|
|
* \param ext A string with an extension. Ex. ".txt"
|
|
*/
|
|
void SetAutoExtension(const std::string& ext) { m_extension = ext; }
|
|
|
|
/**
|
|
* \brief Define extensions that will be accepted as part of a valid file name.
|
|
* \param ext A string with an extension. Ex. ".txt"
|
|
*/
|
|
void AddOptionalExtension(const std::string& ext) { m_extlist.push_back(ext); }
|
|
|
|
/**
|
|
* \brief Set the filename that appears in the edit box when the dialog opens.
|
|
*/
|
|
void SetFilename(const std::string& filename);
|
|
|
|
/**
|
|
* \brief Get the filename that was selected or typed.
|
|
* \return The filename that was typed in the edit box.
|
|
*/
|
|
std::string GetFilename();
|
|
|
|
/**
|
|
* \brief Set whether to check if a file exists when the 'Save' button is pressed,
|
|
* and if the file exists, an "Overwrite existing file?" message is shown.
|
|
* \param doCheck true to check if a file exists when the 'Save' button is pressed.
|
|
*/
|
|
void SetConfirmOverwrite(bool doCheck) { m_confirmOverwrite = doCheck; }
|
|
|
|
//@}
|
|
|
|
private:
|
|
|
|
void StartFileDialog();
|
|
void AdjustDialog();
|
|
|
|
void PopulateList();
|
|
void GetListChoice();
|
|
void SearchList(const std::string &text, bool dirOnly = false);
|
|
|
|
void UpdateAction();
|
|
void UpdatePathLabel();
|
|
void UpdatePublic(bool bPublic);
|
|
|
|
void OpenFolder();
|
|
|
|
bool StartNewFolderMode();
|
|
bool StopNewFolderMode(bool bCancel = false);
|
|
bool EventNewFolder(const Event &event);
|
|
void UpdateNewFolder();
|
|
void CreateNewFolder();
|
|
|
|
bool EventSelectFolder(const Event &event);
|
|
void UpdateSelectFolder();
|
|
|
|
bool ListItemIsFolder();
|
|
bool DirectoryExists(const std::string &name);
|
|
|
|
bool CheckFilename(const std::string& name);
|
|
bool ActionOpen();
|
|
bool ActionSave(bool checkFileExist = false);
|
|
|
|
bool StartAskOverwrite(const std::string& name);
|
|
bool StopAskOverwrite();
|
|
bool EventAskOverwrite(const Event &event);
|
|
|
|
/*!
|
|
* \brief Set the text in the file name edit box.
|
|
* \param edit Pointer to the edit box.
|
|
* \param filename Text to put in the edit box.
|
|
*/
|
|
void SetFilenameField(CEdit* edit, const std::string& filename);
|
|
|
|
/*!
|
|
* \brief Get the current directory with the current sub-directory appended.
|
|
* \param bCreate If true, the directories in question will be created.
|
|
* \return A string with the path of current directory, plus the
|
|
* current sub-directory if any.
|
|
*/
|
|
std::string SearchDirectory(bool bCreate);
|
|
|
|
private:
|
|
|
|
CEventQueue* m_eventQueue;
|
|
CInterface* m_interface;
|
|
|
|
CFileDialog::Type m_dialogtype = Type::None;
|
|
|
|
// EventType for this dialog.
|
|
// With EVENT_NULL, a unique EventType will be used.
|
|
EventType m_windowEvent = EVENT_NULL;
|
|
|
|
glm::vec2 m_windowPos;
|
|
glm::vec2 m_windowDim;
|
|
std::string m_title = "";
|
|
|
|
float m_time;
|
|
float m_lastTimeClickDir;
|
|
bool m_captureClick = false;
|
|
|
|
bool m_newFolderMode = false;
|
|
bool m_selectFolderMode = false;
|
|
bool m_askOverwriteMode = false;
|
|
bool m_confirmOverwrite = false;
|
|
|
|
bool m_public = false;
|
|
std::string m_pathPublic = "";
|
|
std::string m_pathPrivate = "";
|
|
bool m_usePublicPrivate = false;
|
|
|
|
std::string m_basePath = "";
|
|
std::string m_subDirPath = "";
|
|
|
|
std::string m_filename = "";
|
|
|
|
//! The extension to add to a filename if needed
|
|
std::string m_extension = "";
|
|
//! List of extensions accepted as part of a valid file name
|
|
std::vector<std::string> m_extlist = {};
|
|
};
|
|
|
|
} // namespace Ui
|