Browse Source

Clean dialogs and add some windows support

merge-requests/365/head
Jørgen Lien Sellæg 10 years ago
parent
commit
908a7092bc
  1. 9
      src/CMakeLists.txt
  2. 50
      src/dialogs.cc
  3. 14
      src/dialogs.h
  4. 52
      src/dialogs_win.cc
  5. 2
      src/juci.cc
  6. 7
      src/singletons.cc
  7. 2
      src/singletons.h
  8. 253
      src/window.cc
  9. 7
      src/window.h

9
src/CMakeLists.txt

@ -88,13 +88,18 @@ set(source_files juci.h
tooltips.cc
singletons.h
singletons.cc
dialogs.h
cmake.h
cmake.cc)
if(MSYS)
list(APPEND source_files terminal_win.cc)
list(APPEND source_files terminal_win.cc dialogs_win.cc)
list(APPEND source_files dialogs_win.cc)
message("MSYS detected")
else()
list(APPEND source_files terminal.cc)
list(APPEND source_files terminal.cc dialogs.cc)
list(APPEND source_files dialogs.cc)
message("UNIX detected")
endif()
if(${validation})

50
src/dialogs.cc

@ -0,0 +1,50 @@
#include "dialogs.h"
#include "singletons.h"
#include <gtkmm.h>
#include <vector>
std::string open_dialog(const std::string &title,
const std::vector<std::pair<std::string, Gtk::ResponseType>> buttons,
Gtk::FileChooserAction gtk_options) {
Gtk::FileChooserDialog dialog(title, gtk_options);
if(Singleton::directories()->current_path!="")
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), Singleton::directories()->current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
// dialog.set_transient_for(parent); TODO add parent
for (auto &button : buttons)
dialog.add_button(button.first, button.second);
return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
}
std::string Dialog::select_folder() {
return open_dialog("Please choose a folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Open", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
}
std::string Dialog::new_file() {
return open_dialog("Please create a new file",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_SAVE);
}
std::string Dialog::new_folder() {
return open_dialog("Please create a new folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
}
std::string Dialog::select_file() {
return open_dialog("Please choose a folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_OPEN);
}
std::string Dialog::save_file() {
return open_dialog("Please choose a file",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_OPEN);
}

14
src/dialogs.h

@ -0,0 +1,14 @@
#ifndef JUCI_DIALOG_H_
#define JUCI_DIALOG_H_
#include <string>
class Dialog {
public:
static std::string select_folder();
static std::string select_file();
static std::string new_file();
static std::string new_folder();
static std::string save_file();
}; // namespace Dialog
#endif // JUCI_DIALOG_H_

52
src/dialogs_win.cc

@ -0,0 +1,52 @@
#include "dialogs.h"
#include <windows.h>
#include <shlobj.h>
std::string Dialog::select_folder() {
char selected_folder[MAX_PATH];
char init_path[MAX_PATH];
auto title = "Please select a folder";
selected_folder[0] = 0;
init_path[0] = 0;
BROWSEINFOA browse;
browse.hwndOwner = 0;
browse.pidlRoot = NULL;
browse.lpszTitle = title;
browse.pszDisplayName = init_path;
browse.ulFlags = 0;
browse.lpfn = NULL;
auto result = SHBrowseForFolder(&browse);
if(result)
SHGetPathFromIDListA(result, selected_folder);
std::string dir(selected_folder);
return dir;
}
/*
std::string Dialog::new_file() {
return open_dialog("Please create a new file",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_SAVE);
}
std::string Dialog::new_folder() {
return open_dialog("Please create a new folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
}
std::string Dialog::select_file() {
return open_dialog("Please choose a folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_OPEN);
}
std::string Dialog::save_file() {
return open_dialog("Please choose a file",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_OPEN);
}
*/

2
src/juci.cc

@ -45,7 +45,7 @@ void app::on_activate() {
bool first_directory=true;
for(auto &directory: directories) {
if(first_directory) {
window->directories.open(directory);
Singleton::directories()->open(directory);
first_directory=false;
}
else {

7
src/singletons.cc

@ -5,12 +5,19 @@ std::unique_ptr<Directories::Config> Singleton::Config::directories_=std::unique
std::unique_ptr<Terminal::Config> Singleton::Config::terminal_=std::unique_ptr<Terminal::Config>(new Terminal::Config());
std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config());
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>();
std::unique_ptr<Directories> Singleton::directories_=std::unique_ptr<Directories>();
Terminal *Singleton::terminal() {
if(!terminal_)
terminal_=std::unique_ptr<Terminal>(new Terminal());
return terminal_.get();
}
Directories *Singleton::directories() {
if(!directories_)
directories_=std::unique_ptr<Directories>(new Directories());
return directories_.get();
}
std::unique_ptr<Gtk::Label> Singleton::status_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::status() {
if(!status_)

2
src/singletons.h

@ -30,12 +30,14 @@ public:
static std::string log_dir() { return std::string(getenv("HOME")) + "/.juci/log/"; }
static std::string style_dir() { return std::string(getenv("HOME")) + "/.juci/styles/"; }
static Terminal *terminal();
static Directories *directories();
static Gtk::Label *status();
static Gtk::Label *info();
private:
static std::unique_ptr<Terminal> terminal_;
static std::unique_ptr<Gtk::Label> status_;
static std::unique_ptr<Gtk::Label> info_;
static std::unique_ptr<Directories> directories_;
};
#endif // JUCI_SINGLETONS_H_

253
src/window.cc

@ -5,6 +5,7 @@
#include "config.h"
//#include "api.h"
#include <boost/lexical_cast.hpp>
#include "dialogs.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -30,7 +31,7 @@ void Window::generate_keybindings() {
}
}
Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) {
Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::directories()), compiling(false) {
DEBUG("start");
set_title("juCi++");
set_default_size(600, 400);
@ -42,7 +43,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
create_menu();
box.pack_start(menu.get_widget(), Gtk::PACK_SHRINK);
directory_and_notebook_panes.pack1(directories, Gtk::SHRINK);
directory_and_notebook_panes.pack1(*Singleton::directories(), Gtk::SHRINK);
notebook_vbox.pack_start(notebook);
notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK);
directory_and_notebook_panes.pack2(notebook_vbox, Gtk::SHRINK);
@ -60,7 +61,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
box.pack_end(vpaned);
show_all_children();
directories.on_row_activated=[this](const std::string &file) {
Singleton::directories()->on_row_activated=[this](const std::string &file) {
notebook.open(file);
};
@ -100,7 +101,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceRename")))
menu_item->set_sensitive((bool)notebook.get_current_view()->rename_similar_tokens);
directories.select(notebook.get_current_view()->file_path);
Singleton::directories()->select(notebook.get_current_view()->file_path);
if(auto source_view=dynamic_cast<Source::ClangView*>(notebook.get_current_view())) {
if(source_view->reparse_needed) {
@ -140,23 +141,86 @@ void Window::create_menu() {
hide();
});
menu.action_group->add(Gtk::Action::create("FileNewFile", "New File"), Gtk::AccelKey(menu.key_map["new_file"]), [this]() {
new_file_dialog();
boost::filesystem::path path = Dialog::new_file();
if(path!="") {
if(boost::filesystem::exists(path)) {
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
}
else {
if(juci::filesystem::write(path)) {
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
notebook.open(path.string());
Singleton::terminal()->print("New file "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n");
}
}
});
menu.action_group->add(Gtk::Action::create("FileNewFolder", "New Folder"), Gtk::AccelKey(menu.key_map["new_folder"]), [this]() {
new_folder_dialog();
auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
boost::filesystem::path path = Dialog::new_folder();
if(boost::filesystem::last_write_time(path)>=time_now) {
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
Singleton::terminal()->print("New folder "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
Singleton::directories()->select(path);
});
menu.action_group->add(Gtk::Action::create("FileNewProject", "New Project"));
menu.action_group->add(Gtk::Action::create("FileNewProjectCpp", "C++"), [this]() {
new_cpp_project_dialog();
boost::filesystem::path project_path = Dialog::new_folder();
auto project_name=project_path.filename().string();
for(size_t c=0;c<project_name.size();c++) {
if(project_name[c]==' ')
project_name[c]='_';
}
auto cmakelists_path=project_path;
cmakelists_path+="/CMakeLists.txt";
auto cpp_main_path=project_path;
cpp_main_path+="/main.cpp";
if(boost::filesystem::exists(cmakelists_path)) {
Singleton::terminal()->print("Error: "+cmakelists_path.string()+" already exists.\n");
return;
}
if(boost::filesystem::exists(cpp_main_path)) {
Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n");
return;
}
std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall\")\n\nadd_executable("+project_name+" main.cpp)\n";
std::string cpp_main="#include <iostream>\n\nusing namespace std;\n\nint main() {\n cout << \"Hello World!\" << endl;\n\n return 0;\n}\n";
if(juci::filesystem::write(cmakelists_path, cmakelists) && juci::filesystem::write(cpp_main_path, cpp_main)) {
Singleton::directories()->open(project_path);
notebook.open(cpp_main_path);
Singleton::terminal()->print("C++ project "+project_name+" created.\n");
}
else
Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n");
});
menu.action_group->add(Gtk::Action::create("FileOpenFile", "Open File"), Gtk::AccelKey(menu.key_map["open_file"]), [this]() {
open_file_dialog();
notebook.open(Dialog::select_file());
});
menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(menu.key_map["open_folder"]), [this]() {
open_folder_dialog();
Singleton::directories()->open(Dialog::select_folder());
});
menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() {
save_file_dialog();
auto path = Dialog::save_file();
if(path.size()>0) {
std::ofstream file(path);
if(file) {
file << notebook.get_current_view()->get_buffer()->get_text();
file.close();
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
notebook.open(path);
Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n");
}
else
Singleton::terminal()->print("Error saving file\n");
}
});
menu.action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu.key_map["save"]), [this]() {
@ -301,7 +365,7 @@ void Window::create_menu() {
if(content!="") {
last_run_command=content;
Singleton::terminal()->async_print("Running: "+content+'\n');
Singleton::terminal()->async_execute(content, directories.current_path, [this, content](int exit_code){
Singleton::terminal()->async_execute(content, Singleton::directories()->current_path, [this, content](int exit_code){
Singleton::terminal()->async_print(content+" returned: "+boost::lexical_cast<std::string>(exit_code)+'\n');
});
}
@ -388,173 +452,6 @@ void Window::hide() {
Gtk::Window::hide();
}
void Window::new_file_dialog() {
Gtk::FileChooserDialog dialog("Please create a new file", Gtk::FILE_CHOOSER_ACTION_SAVE);
if(directories.current_path!="")
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("Save", Gtk::RESPONSE_OK);
int result = dialog.run();
if(result==Gtk::RESPONSE_OK) {
boost::filesystem::path path = dialog.get_filename();
if(path!="") {
if(boost::filesystem::exists(path)) {
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
}
else {
if(juci::filesystem::write(path)) {
if(directories.current_path!="")
directories.update();
notebook.open(path.string());
Singleton::terminal()->print("New file "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n");
}
}
}
}
void Window::new_folder_dialog() {
auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
Gtk::FileChooserDialog dialog("Please create a new folder", Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
if(directories.current_path!="")
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("Create", Gtk::RESPONSE_OK);
int result = dialog.run();
if(result==Gtk::RESPONSE_OK) {
boost::filesystem::path path=dialog.get_filename();
if(boost::filesystem::last_write_time(path)>=time_now) {
if(directories.current_path!="")
directories.update();
Singleton::terminal()->print("New folder "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
directories.select(path);
}
}
void Window::new_cpp_project_dialog() {
Gtk::FileChooserDialog dialog("Please create and/or choose a folder", Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
if(directories.current_path!="")
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("Create", Gtk::RESPONSE_OK);
int result = dialog.run();
if(result==Gtk::RESPONSE_OK) {
boost::filesystem::path project_path=dialog.get_filename();
auto project_name=project_path.filename().string();
for(size_t c=0;c<project_name.size();c++) {
if(project_name[c]==' ')
project_name[c]='_';
}
auto cmakelists_path=project_path;
cmakelists_path+="/CMakeLists.txt";
auto cpp_main_path=project_path;
cpp_main_path+="/main.cpp";
if(boost::filesystem::exists(cmakelists_path)) {
Singleton::terminal()->print("Error: "+cmakelists_path.string()+" already exists.\n");
return;
}
if(boost::filesystem::exists(cpp_main_path)) {
Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n");
return;
}
std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall\")\n\nadd_executable("+project_name+" main.cpp)\n";
std::string cpp_main="#include <iostream>\n\nusing namespace std;\n\nint main() {\n cout << \"Hello World!\" << endl;\n\n return 0;\n}\n";
if(juci::filesystem::write(cmakelists_path, cmakelists) && juci::filesystem::write(cpp_main_path, cpp_main)) {
directories.open(project_path);
notebook.open(cpp_main_path);
Singleton::terminal()->print("C++ project "+project_name+" created.\n");
}
else
Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n");
}
}
void Window::open_folder_dialog() {
Gtk::FileChooserDialog dialog("Please choose a folder", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
if(directories.current_path!="")
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("Open", Gtk::RESPONSE_OK);
int result = dialog.run();
if(result==Gtk::RESPONSE_OK) {
std::string project_path=dialog.get_filename();
directories.open(project_path);
}
}
void Window::open_file_dialog() {
Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN);
if(directories.current_path!="")
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("Open", Gtk::RESPONSE_OK);
int result = dialog.run();
if(result==Gtk::RESPONSE_OK) {
std::string path = dialog.get_filename();
notebook.open(path);
}
}
void Window::save_file_dialog() {
if(notebook.get_current_page()==-1)
return;
Gtk::FileChooserDialog dialog(*this, "Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE);
gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), notebook.get_current_view()->file_path.string().c_str());
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("Save", Gtk::RESPONSE_OK);
int result = dialog.run();
if(result==Gtk::RESPONSE_OK) {
auto path = dialog.get_filename();
if(path.size()>0) {
std::ofstream file(path);
if(file) {
file << notebook.get_current_view()->get_buffer()->get_text();
file.close();
if(directories.current_path!="")
directories.update();
notebook.open(path);
Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n");
}
else
Singleton::terminal()->print("Error saving file\n");
}
}
}
void Window::search_and_replace_entry() {
entry_box.clear();
entry_box.labels.emplace_back();

7
src/window.h

@ -12,7 +12,6 @@
class Window : public Gtk::Window {
public:
Window();
Directories directories;
Notebook notebook;
class Config {
public:
@ -41,12 +40,6 @@ private:
void create_menu();
void hide();
void new_file_dialog();
void new_folder_dialog();
void new_cpp_project_dialog();
void open_folder_dialog();
void open_file_dialog();
void save_file_dialog();
void search_and_replace_entry();
void goto_line_entry();
void rename_token_entry();

Loading…
Cancel
Save