From 5f3812f385535b127559aba584f6528c0883bdc2 Mon Sep 17 00:00:00 2001 From: daleclack Date: Tue, 13 Jul 2021 14:39:03 +0800 Subject: [PATCH] Add gtk95 --- Gtkmm3/gtk95_textview2/meson.build | 30 +++ Gtkmm3/gtk95_textview2/src/MyWin.cc | 185 ++++++++++++++++ Gtkmm3/gtk95_textview2/src/MyWin.hh | 29 +++ Gtkmm3/gtk95_textview2/src/main.cc | 7 + Gtkmm3/text_types.hh | 328 ++++++++++++++++++++++++++++ 5 files changed, 579 insertions(+) create mode 100644 Gtkmm3/gtk95_textview2/meson.build create mode 100644 Gtkmm3/gtk95_textview2/src/MyWin.cc create mode 100644 Gtkmm3/gtk95_textview2/src/MyWin.hh create mode 100644 Gtkmm3/gtk95_textview2/src/main.cc create mode 100644 Gtkmm3/text_types.hh diff --git a/Gtkmm3/gtk95_textview2/meson.build b/Gtkmm3/gtk95_textview2/meson.build new file mode 100644 index 0000000..6c9addd --- /dev/null +++ b/Gtkmm3/gtk95_textview2/meson.build @@ -0,0 +1,30 @@ +#A Simple Project Test +project('gtk95', 'cpp', + default_options : ['c_std=c17', 'cpp_std=c++17']) + +#Initalize variants +# gnome=import('gnome') + +#Compile Resource +# gresources = gnome.compile_resources( +# 'resources', 'res/gtk91.resource.xml', +# source_dir: 'res', +# c_name: 'resources' +# ) + +#The Gtkmm Library as a dependency +gtkdep = dependency('gtkmm-3.0') + +#Additional include dirs +dir_include = include_directories('..') + +#Use Different Build Opinions in windows and Linux +if host_machine.system() == 'windows' + win=import('windows') + icon_res=win.compile_resources('icon.rc') + executable('gtk95', icon_res, 'src/main.cc', 'src/MyWin.cc', dependencies : gtkdep, + win_subsystem : 'windows', include_directories : dir_include) +else + executable('gtk95', 'src/main.cc', 'src/MyWin.cc', dependencies : gtkdep, + include_directories : dir_include) +endif diff --git a/Gtkmm3/gtk95_textview2/src/MyWin.cc b/Gtkmm3/gtk95_textview2/src/MyWin.cc new file mode 100644 index 0000000..68ffa1c --- /dev/null +++ b/Gtkmm3/gtk95_textview2/src/MyWin.cc @@ -0,0 +1,185 @@ +#include "MyWin.hh" +#include "text_types.hh" +#include + +MyWin::MyWin() +:vbox(Gtk::ORIENTATION_VERTICAL,5), +hbox(Gtk::ORIENTATION_HORIZONTAL,5), +btnbox(Gtk::ORIENTATION_VERTICAL,5), +btn_copy("Copy"), +btn_paste("Paste"), +btn_open("Open"), +btn_save("Save") +{ + //Initalize Window + set_default_size(800,450); + set_icon_name("org.gtk.daleclack"); + + //Initalize Text Buffers + buffer1=textview1.get_buffer(); + buffer1->signal_changed().connect(sigc::mem_fun(*this,&MyWin::buffer1_changed)); + + //Pack Widgets + sw1.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); + sw1.add(textview1); + btnbox.set_valign(Gtk::ALIGN_CENTER); + btnbox.pack_start(btn_copy,Gtk::PACK_SHRINK); + btnbox.pack_start(btn_paste,Gtk::PACK_SHRINK); + btnbox.pack_start(btn_open,Gtk::PACK_SHRINK); + btnbox.pack_start(btn_save,Gtk::PACK_SHRINK); + hbox.pack_start(sw1); + hbox.pack_start(btnbox,Gtk::PACK_SHRINK); + + btn_open.signal_clicked().connect(sigc::mem_fun(*this,&MyWin::btnopen_clicked)); + btn_save.signal_clicked().connect(sigc::mem_fun(*this,&MyWin::btnsave_clicked)); + btn_copy.signal_clicked().connect(sigc::mem_fun(*this,&MyWin::btncopy_clicked)); + btn_paste.signal_clicked().connect(sigc::mem_fun(*this,&MyWin::btnpaste_clicked)); + + //A InfoBar + infobar.add_button("OK",Gtk::RESPONSE_OK); + infobar.signal_response().connect(sigc::mem_fun(*this,&MyWin::infobar_response)); + infobox=dynamic_cast(infobar.get_content_area()); + infobox->pack_start(label1); + vbox.pack_start(infobar,Gtk::PACK_SHRINK); + + //Disable Copy button + btn_copy.set_sensitive(false); + + //Show everything + vbox.pack_start(hbox); + add(vbox); + show_all_children(); + infobar.hide(); +} + +void MyWin::btnopen_clicked(){ + //Create a dialog + dialog=Gtk::FileChooserNative::create("Open a text file",*this, + Gtk::FILE_CHOOSER_ACTION_OPEN,"OK","Cancel"); + + dialog->signal_response().connect(sigc::mem_fun(*this,&MyWin::opendialog_response)); + + //Add Filters + auto filter=Gtk::FileFilter::create(); + filter->set_name("Text Files"); + if(mimetype_supported()){ + filter->add_mime_type("text/*"); + }else{ + for(int i = 0; supported_globs != NULL && supported_globs[i] != NULL; i++){ + const char *glob = supported_globs[i]; + filter->add_pattern(glob); + } + } + dialog->add_filter(filter); + + auto filter_any=Gtk::FileFilter::create(); + filter_any->set_name("Any Files"); + filter_any->add_pattern("*"); + dialog->add_filter(filter_any); + + dialog->show(); +} + +void MyWin::opendialog_response(int response){ + if(response==Gtk::RESPONSE_ACCEPT){ + //Load Contents of a file + auto file=dialog->get_file(); + char * contents; + gsize length; + if(file->load_contents(contents,length)){ + buffer1->set_text(contents); + } + } + dialog.reset(); +} + +void MyWin::btnsave_clicked(){ + //Create a dialog + dialog=Gtk::FileChooserNative::create("Save file",*this, + Gtk::FILE_CHOOSER_ACTION_SAVE,"OK","Cancel"); + + dialog->signal_response().connect(sigc::mem_fun(*this,&MyWin::savedialog_response)); + + //Add Filters + auto filter=Gtk::FileFilter::create(); + filter->set_name("Text Files"); + if(mimetype_supported()){ + filter->add_mime_type("text/*"); + }else{ + for(int i = 0; supported_globs != NULL && supported_globs[i] != NULL; i++){ + const char *glob = supported_globs[i]; + filter->add_pattern(glob); + } + } + dialog->add_filter(filter); + + auto filter_any=Gtk::FileFilter::create(); + filter_any->set_name("Any Files"); + filter_any->add_pattern("*"); + dialog->add_filter(filter_any); + + dialog->show(); +} + +void MyWin::savedialog_response(int response){ + if(response==Gtk::RESPONSE_ACCEPT){ + //Get Filename + auto file=dialog->get_file(); + std::string filename=file->get_path(); + //Get Text + Glib::ustring text; + text=buffer1->get_text(); + //Save to a file + std::ofstream outfile; + outfile.open(filename,std::ios_base::out); + outfile<get_selection_bounds(start,end)){ + text=buffer1->get_text(start,end); + }else{ + text=buffer1->get_text(); + } + + //Get Clipboard and set text + auto refClipboard=Gtk::Clipboard::get(); + refClipboard->set_text(text); + + //Show InfoBar + label1.set_label("The Text is copyed"); + infobar.show(); +} + +void MyWin::btnpaste_clicked(){ + //Get ClipBoard + auto refClipboard=Gtk::Clipboard::get(); + refClipboard->request_text(sigc::mem_fun(*this,&MyWin::clipboard_receive)); +} + +void MyWin::clipboard_receive(const Glib::ustring &text){ + if(buffer1->insert_interactive_at_cursor(text)){ + //Show InfoBar + label1.set_label("The Text is Pasted at cursor position"); + infobar.show(); + }else{ + //Show InfoBar + label1.set_label("Text Paste Error!"); + infobar.show(); + } +} + +void MyWin::infobar_response(int response){ + infobar.hide(); +} diff --git a/Gtkmm3/gtk95_textview2/src/MyWin.hh b/Gtkmm3/gtk95_textview2/src/MyWin.hh new file mode 100644 index 0000000..9bfb06d --- /dev/null +++ b/Gtkmm3/gtk95_textview2/src/MyWin.hh @@ -0,0 +1,29 @@ +#pragma once + +#include + +class MyWin : public Gtk::Window{ +public: + MyWin(); +private: + //Child widgets + Gtk::Box vbox,hbox,btnbox,*infobox; + Gtk::ScrolledWindow sw1,sw2; + Glib::RefPtr buffer1; + Gtk::TextView textview1; + Gtk::Button btn_copy,btn_paste,btn_open,btn_save; + Gtk::InfoBar infobar; + Gtk::Label label1; + //File Dialog + Glib::RefPtr dialog; + //Signal Handlers + void btnopen_clicked(); + void opendialog_response(int response); + void btnsave_clicked(); + void savedialog_response(int response); + void btncopy_clicked(); + void btnpaste_clicked(); + void buffer1_changed(); + void clipboard_receive(const Glib::ustring &text); + void infobar_response(int response); +}; diff --git a/Gtkmm3/gtk95_textview2/src/main.cc b/Gtkmm3/gtk95_textview2/src/main.cc new file mode 100644 index 0000000..3c8b613 --- /dev/null +++ b/Gtkmm3/gtk95_textview2/src/main.cc @@ -0,0 +1,7 @@ +#include "MyWin.hh" + +int main(int argc,char **argv){ + auto app=Gtk::Application::create(argc,argv,"org.gtk.daleclack"); + MyWin window; + return app->run(window); +} diff --git a/Gtkmm3/text_types.hh b/Gtkmm3/text_types.hh new file mode 100644 index 0000000..67be177 --- /dev/null +++ b/Gtkmm3/text_types.hh @@ -0,0 +1,328 @@ +static const char *const supported_globs[] = +{ + "*.abw", + "*.adb", + "*.ads", + "*.al", + "*.asc", + "*.asp", + "*.ass", + "*.atom", + "*.automount", + "*.awk", + "*.bib", + "*.build", + "*.c", + "*.c++", + "*.cbl", + "*.cc", + "*.ccmx", + "*.cl", + "*.cls", + "*.cmake", + "*.cob", + "*.coffee", + "*.cpp", + "*.cs", + "*.csh", + "*.css", + "*.csv", + "*.csvs", + "*.cue", + "*.cxx", + "*.d", + "*.dbk", + "*.dcl", + "*.desktop", + "*.device", + "*.di", + "*.dia", + "*.diff", + "*.docbook", + "*.dot", + "*.dsl", + "*.dtd", + "*.dtx", + "*.e", + "*.eif", + "*.el", + "*.eml", + "*.ent", + "*.eps", + "*.epsf", + "*.epsi", + "*.erl", + "*.es", + "*.etx", + "*.f", + "*.f90", + "*.f95", + "*.fb2", + "*.feature", + "*.fl", + "*.flatpakref", + "*.flatpakrepo", + "*.fo", + "*.fodg", + "*.fodp", + "*.fods", + "*.fodt", + "*.for", + "*.gcode", + "*.gcrd", + "*.geojson", + "*.glade", + "*.gml", + "*.gnuplot", + "*.go", + "*.gp", + "*.gpg", + "*.gplt", + "*.gpx", + "*.gradle", + "*.groovy", + "*.gs", + "*.gsf", + "*.gsh", + "*.gv", + "*.gvp", + "*.gvy", + "*.gy", + "*.h", + "*.h++", + "*.hh", + "*.hp", + "*.hpp", + "*.hs", + "*.htm", + "*.html", + "*.hxx", + "*.ica", + "*.ics", + "*.idl", + "*.iges", + "*.igs", + "*.ime", + "*.imy", + "*.ins", + "*.iptables", + "*.ipynb", + "*.it87", + "*.jad", + "*.java", + "*.jnlp", + "*.jrd", + "*.js", + "*.jsm", + "*.json", + "*.jsonld", + "*.json-patch", + "*.kdelnk", + "*.key", + "*.kino", + "*.kml", + "*.la", + "*.latex", + "*.ldif", + "*.lhs", + "*.log", + "*.ltx", + "*.lua", + "*.ly", + "*.lyx", + "*.m", + "*.m1u", + "*.m3u", + "*.m3u8", + "*.m4", + "*.m4u", + "*.mab", + "*.mak", + "*.man", + "*.manifest", + "*.markdown", + "*.mbox", + "*.mc2", + "*.md", + "*.me", + "*.meta4", + "*.metalink", + "*.mgp", + "*.mjs", + "*.mk", + "*.mkd", + "*.ml", + "*.mli", + "*.mm", + "*.mml", + "*.mo", + "*.moc", + "*.mof", + "*.mount", + "*.mrl", + "*.mrml", + "*.ms", + "*.mup", + "*.mxu", + "*.nb", + "*.nfo", + "*.not", + "*.nzb", + "*.ocl", + "*.ooc", + "*.opml", + "*.owl", + "*.owx", + "*.p", + "*.p7s", + "*.pas", + "*.patch", + "*.path", + "*.perl", + "*.pfa", + "*.pfb", + "*.pgn", + "*.pgp", + "*.php", + "*.php3", + "*.php4", + "*.php5", + "*.phps", + "*.pkr", + "*.pl", + "*.pm", + "*.po", + "*.pod", + "*.pot", + "*.ps", + "*.py", + "*.py3", + "*.py3x", + "*.pyx", + "*.qml", + "*.qmlproject", + "*.qmltypes", + "*.qti", + "*.raml", + "*.rb", + "*.rdf", + "*.rdfs", + "*.rej", + "*.rnc", + "*.rng", + "*.roff", + "*.rs", + "*.rss", + "*.rst", + "*.rt", + "*.rtf", + "*.rtx", + "*.sami", + "*.sass", + "*.scala", + "*.scm", + "*.scope", + "*.scss", + "*.sdp", + "*.service", + "*.sgf", + "*.sgm", + "*.sgml", + "*.sh", + "*.shape", + "*.sig", + "*.siv", + "*.skr", + "*.slice", + "*.slk", + "*.smi", + "*.smil", + "*.sml", + "*.socket", + "*.spec", + "*.sql", + "*.src", + "*.srt", + "*.ss", + "*.ssa", + "*.sty", + "*.sub", + "*.sv", + "*.svg", + "*.svh", + "*.swap", + "*.sylk", + "*.t", + "*.t2t", + "*.target", + "*.tcl", + "*.tex", + "*.texi", + "*.texinfo", + "*.theme", + "*.timer", + "*.tk", + "*.toc", + "*.tr", + "*.trig", + "*.ts", + "*.tsv", + "*.ttl", + "*.ttx", + "*.twig", + "*.txt", + "*.ufraw", + "*.ui", + "*.uil", + "*.uue", + "*.v", + "*.vala", + "*.vapi", + "*.vcard", + "*.vcf", + "*.vcs", + "*.vct", + "*.vhd", + "*.vhdl", + "*.vlc", + "*.vrm", + "*.vrml", + "*.vtt", + "*.wml", + "*.wmls", + "*.wrl", + "*.wsgi", + "*.xbel", + "*.xbl", + "*.xht", + "*.xhtml", + "*.xlf", + "*.xliff", + "*.xmi", + "*.xml", + "*.xsd", + "*.xsl", + "*.xslfo", + "*.xslt", + "*.xspf", + "*.xul", + "*.yaml", + "*.yml", + "*.zabw", + NULL +}; + +static inline bool mimetype_supported(){ + /* Note that the #ifdef could be moved to where this function is called, to have + * much more code between the #ifdef/#else/#endif. The goal is to always compile + * all the code on all platforms, to catch compilation problems earlier. + */ + #ifdef G_OS_WIN32 + /* See the GtkFileChooserNative documentation, a GtkFileFilter with + * mime-types is not supported on Windows. + */ + return false; + #else + return true; + #endif +}