summaryrefslogtreecommitdiffstats
path: root/qtruby/rubylib/examples/textedit/textedit.rb
blob: db905b4f96eb23ccb2587623ce85d5a86516aa47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/ruby -w

require 'Qt'
require 'rexml/document'

require '../base/rui.rb'

class MyTextEditor < Qt::TextEdit
   signals 'saved()'
   slots 'insert_icon()', 'new()', 'open()', 'save_as()'
   def initialize(w = nil)
      @images = {}
      @@next_image_id = 0
      super(w)
      self.setTextFormat(Qt::RichText)
   end
   def insert_richtext(richtext)
      # todo, use a rand string
      unique_string = '000___xxx123456789xxx___xxx123456789xxx___000'
      insert(unique_string)
      txt = self.text().gsub(unique_string, richtext)
      self.setText(txt)
   end
   def next_image_id
      @@next_image_id += 1
   end
   def load_image(fname, image_id)
      pixmap = Qt::Pixmap.new(fname)
      msfactory = Qt::MimeSourceFactory.defaultFactory
      msfactory.setPixmap(image_id, pixmap)
      @images[image_id] = fname
      image_id
   end
   def insert_icon
      fname = Qt::FileDialog.getOpenFileName
      return if fname.nil?
      image_id = "image_#{next_image_id}"
      load_image(fname, image_id)
      insert_richtext('<qt><img source="'+image_id+'"></qt>')
   end
   def createPopupMenu(pos) # virtual
      pm = Qt::PopupMenu.new
      pm.insertItem("Insert Image!", self, SLOT('insert_icon()'))
      pm
   end
   def has_metadata
      !@images.empty?
   end
   def metadata_fname(fname)
      "#{fname}.metadata.xml"
   end
   def attempt_metadata_load(fname)
      return unless File.exists?(metadata_fname(fname))
      file = File.open(metadata_fname(fname))
      @xmldoc = REXML::Document.new file
      @xmldoc.root.elements.each("image") {
         |image|
         image_id = image.attributes["ident"]
         img_fname = image.attributes["filename"]
         load_image(img_fname, image_id)
      }
   end
   def metadata_save_if_has(fname)
      return if not has_metadata
      metadata_doc = REXML::Document.new '<metadata/>'
      @images.each {
         |id, img_fname|
         metadata_doc.root.add_element("image", {"filename"=>img_fname, "ident"=>id})
      }
      file = File.new(metadata_fname(fname), "w")
      file.puts(metadata_doc)
      file.close
   end
   def metadata_clear
      @images = {}
   end
   def new(txt = "")
      metadata_clear
      self.setText(txt)
   end
   def open
      fname = Qt::FileDialog.getOpenFileName
      return if fname.nil?
      unless File.exists?(fname)
         Qt::MessageBox.critical(self, "File Does Not Exist", "Sorry, unable to find the requested file!")
         return
      end
      return if fname.nil?
      txt = File.open(fname).gets(nil)
      metadata_clear
      attempt_metadata_load(fname)
      self.setText(txt)
   end
   def save_as
      fname = Qt::FileDialog.getSaveFileName
      return if fname.nil?
      if File.exists?(fname)
         Qt::MessageBox.critical(self, "File Already Exists", "Sorry, file already exists. Please choose a non-existing filename!")
         return save_as
      end
      file = File.new(fname, "w")
      file.puts(text())
      file.close
      metadata_save_if_has(fname)
      emit saved()
   end
end

class MyWidget < Qt::MainWindow
   slots 'text_changed()', 'saved()'
   def initialize()
      super
      @editor = MyTextEditor.new(self)
      connect(@editor, SIGNAL('textChanged()'), self, SLOT('text_changed()'))
      connect(@editor, SIGNAL('saved()'), self, SLOT('saved()'))

      fileTools = Qt::ToolBar.new(self, "file operations")
      fileMenu = Qt::PopupMenu.new(self)

      actions = [
         RAction.new("&New",  Icons::FILE_NEW, @editor, SLOT('new()'), [fileTools, fileMenu]),
         RAction.new("&Open...", Icons::FILE_OPEN, @editor, SLOT('open()'), [fileTools, fileMenu]),
         @save = RAction.new("Save &As...", Icons::FILE_SAVE_AS, @editor, SLOT('save_as()'), [fileTools, fileMenu]),
         RSeperator.new([fileMenu]),
         RAction.new("E&xit", Icons::EXIT, $qApp, SLOT('quit()'), [fileMenu])
      ]

      build_actions(actions)

      menubar = Qt::MenuBar.new(self)
      menubar.insertItem("&File", fileMenu)

      self.setCentralWidget(@editor)
   end
   def saved
      @save.action.setEnabled(false)
   end
   def text_changed
      @save.action.setEnabled(true)
   end
end

a = Qt::Application.new(ARGV)

w = MyWidget.new
w.show

a.setMainWidget(w)
a.exec()
exit