root / trunk / gummi / GummiGUI.py @ 299
History | View | Annotate | Download (24.7 KB)
| 1 | #!/usr/bin/python
|
|---|---|
| 2 | # -*- encoding: utf-8 -*-
|
| 3 | |
| 4 | # Copyright (c) 2009 Alexander van der Mey <alexvandermey@gmail.com>
|
| 5 | |
| 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 7 | # of this software and associated documentation files (the "Software"), to deal
|
| 8 | # in the Software without restriction, including without limitation the rights
|
| 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 10 | # copies of the Software, and to permit persons to whom the Software is
|
| 11 | # furnished to do so, subject to the following conditions:
|
| 12 | #
|
| 13 | # The above copyright notice and this permission notice shall be included in
|
| 14 | # all copies or substantial portions of the Software.
|
| 15 | #
|
| 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
| 22 | # THE SOFTWARE.
|
| 23 | |
| 24 | import os |
| 25 | import sys |
| 26 | import glib |
| 27 | import gtk |
| 28 | import pango |
| 29 | import traceback |
| 30 | |
| 31 | import Importer |
| 32 | import UpdateCheck |
| 33 | import Template |
| 34 | import Preferences |
| 35 | |
| 36 | |
| 37 | class MainGUI: |
| 38 | |
| 39 | def __init__(self, parent, config, iofunc, biblio): |
| 40 | self.core = parent
|
| 41 | self.config = config
|
| 42 | self.editorpane = self.core.editorpane |
| 43 | self.previewpane = self.core.previewpane |
| 44 | self.iofunc = iofunc
|
| 45 | self.biblio = biblio
|
| 46 | |
| 47 | self.path = self.core.path |
| 48 | self.tempdir = self.core.tempdir |
| 49 | self.builder = self.core.builder |
| 50 | self.exitinterrupt = False |
| 51 | |
| 52 | self.mainwindow = self.builder.get_object("mainwindow") |
| 53 | self.toolbar = self.builder.get_object("toolbar") |
| 54 | self.mainnotebook = self.builder.get_object("main_notebook") |
| 55 | self.editorscroll = self.builder.get_object("editor_scroll") |
| 56 | self.drawarea = self.builder.get_object("preview_drawarea") |
| 57 | self.preview_toolbar = self.builder.get_object("preview_toolbar") |
| 58 | self.bibprogressbar = self.builder.get_object("bibprogressbar") |
| 59 | self.bibprogressmon = self.builder.get_object("bibprogressmon") |
| 60 | self.bibprogressval = 0 |
| 61 | self.list_biblios = self.builder.get_object("list_biblios") |
| 62 | |
| 63 | if self.config.get_value("view", "toolbar"): |
| 64 | menu_toolbar = self.builder.get_object("menu_toolbar") |
| 65 | menu_toolbar.set_active(True)
|
| 66 | self.toolbar.show()
|
| 67 | |
| 68 | if self.config.get_value("view", "statusbar"): |
| 69 | menu_statusbar = self.builder.get_object("menu_statusbar") |
| 70 | menu_statusbar.set_active(True)
|
| 71 | self.iofunc.statusbar.show()
|
| 72 | |
| 73 | self.hpaned = self.builder.get_object("hpaned") |
| 74 | mainwidth = self.mainwindow.get_size()[0] |
| 75 | self.hpaned.set_position(mainwidth/2) |
| 76 | |
| 77 | self.editorscroll.add(self.editorpane.editorviewer) |
| 78 | self.importgui = ImportGUI(self.builder, self.editorpane) |
| 79 | self.recentgui = RecentGUI(self.builder, self.config, self) |
| 80 | self.searchgui = SearchGUI(self.builder, self.editorpane) |
| 81 | self.builder.connect_signals(self) #split signals? |
| 82 | |
| 83 | |
| 84 | def main(self): |
| 85 | self.mainwindow.show_all()
|
| 86 | gtk.main() |
| 87 | |
| 88 | def set_window_title(self, filename): |
| 89 | self.mainwindow.set_title \
|
| 90 | (os.path.basename(filename) + " - Gummi")
|
| 91 | |
| 92 | def on_menu_new_activate(self, menuitem, data=None): |
| 93 | if self.check_for_save(): self.on_menu_save_activate(None, None) |
| 94 | self.editorpane.fill_buffer \
|
| 95 | (self.config.get_value("default_text", "welcome")) |
| 96 | self.editorpane.editorbuffer.set_modified(False) |
| 97 | self.filename = None |
| 98 | self.iofunc.make_environment(self.filename) |
| 99 | |
| 100 | def on_menu_template_activate(self, menuitem, data=None): |
| 101 | self.template_doc = Template.Template(self.builder, self.path) |
| 102 | |
| 103 | def on_menu_open_activate(self, menuitem, data=None): |
| 104 | if os.getcwd() == self.tempdir: |
| 105 | os.chdir(os.environ['HOME'])
|
| 106 | if self.check_for_save(): self.on_menu_save_activate(None, None) |
| 107 | filename = self.get_open_filename()
|
| 108 | if filename: self.load_document(filename) |
| 109 | |
| 110 | def on_menu_save_activate(self, menuitem, data=None): |
| 111 | if os.getcwd() == self.tempdir: |
| 112 | os.chdir(os.environ['HOME'])
|
| 113 | if self.iofunc.filename is None: |
| 114 | filename = self.get_save_filename()
|
| 115 | if filename: self.save_document(filename) |
| 116 | else: self.save_document(None) |
| 117 | |
| 118 | def on_menu_saveas_activate(self, menuitem, data=None): |
| 119 | if os.getcwd() == self.tempdir: |
| 120 | os.chdir(os.environ['HOME'])
|
| 121 | self.filename = self.get_save_filename() |
| 122 | if self.filename: self.save_document(self.filename) |
| 123 | |
| 124 | def on_menu_recent_activate(self, widget, data=None): |
| 125 | self.recentgui.activate_recentfile(widget)
|
| 126 | |
| 127 | def on_menu_undo_activate(self, menuitem, data=None): |
| 128 | self.editorpane.undo_change()
|
| 129 | |
| 130 | def on_menu_redo_activate(self, menuitem, data=None): |
| 131 | self.editorpane.redo_change()
|
| 132 | |
| 133 | def on_menu_cut_activate(self, menuitem, data=None): |
| 134 | buff = self.editorpane.editorviewer.get_buffer()
|
| 135 | buff.cut_clipboard (gtk.clipboard_get(), True)
|
| 136 | self.editorpane.set_buffer_changed()
|
| 137 | |
| 138 | def on_menu_copy_activate(self, menuitem, data=None): |
| 139 | buff = self.editorpane.editorviewer.get_buffer()
|
| 140 | buff.copy_clipboard (gtk.clipboard_get()) |
| 141 | |
| 142 | def on_menu_paste_activate(self, menuitem, data=None): |
| 143 | buff = self.editorpane.editorviewer.get_buffer()
|
| 144 | buff.paste_clipboard (gtk.clipboard_get(), None, True) |
| 145 | self.editorpane.set_buffer_changed()
|
| 146 | |
| 147 | def on_menu_delete_activate(self, menuitem, data=None): |
| 148 | buff = self.editorpane.editorviewer.get_buffer()
|
| 149 | buff.delete_selection (False, True) |
| 150 | |
| 151 | def on_menu_selectall_activate(self, menuitem, data=None): |
| 152 | buff = self.editorpane.editorviewer.get_buffer()
|
| 153 | buff.select_range(buff.get_start_iter(),buff.get_end_iter()) |
| 154 | |
| 155 | def on_menu_find_activate(self, menuitem, data=None): |
| 156 | self.searchgui.show_searchwindow()
|
| 157 | |
| 158 | def on_menu_findnext_activate(self, menuitem, data=None): |
| 159 | self.editorpane.jumpto_searchresult(1) |
| 160 | |
| 161 | def on_menu_findprev_activate(self, menuitem, data=None): |
| 162 | self.editorpane.jumpto_searchresult(-1) |
| 163 | |
| 164 | def on_menu_fullscreen_toggled(self, menuitem, data=None): |
| 165 | if menuitem.get_active():
|
| 166 | self.mainwindow.fullscreen()
|
| 167 | else:
|
| 168 | self.mainwindow.unfullscreen()
|
| 169 | |
| 170 | def on_menu_toolbar_toggled(self, menuitem, data=None): |
| 171 | if menuitem.get_active():
|
| 172 | self.toolbar.show()
|
| 173 | self.config.set_value("view", "toolbar", True) |
| 174 | else:
|
| 175 | self.toolbar.hide()
|
| 176 | self.config.set_value("view", "toolbar", False) |
| 177 | |
| 178 | def on_menu_statusbar_toggled(self, menuitem, data=None): |
| 179 | if menuitem.get_active():
|
| 180 | self.iofunc.statusbar.show()
|
| 181 | self.config.set_value("view", "statusbar", True) |
| 182 | else:
|
| 183 | self.iofunc.statusbar.hide()
|
| 184 | self.config.set_value("view", "statusbar", False) |
| 185 | |
| 186 | def on_button_searchwindow_close_clicked(self, button, data=None): |
| 187 | self.searchgui.close_searchwindow()
|
| 188 | |
| 189 | def on_button_searchwindow_find_clicked(self, button, data=None): |
| 190 | self.searchgui.start_search()
|
| 191 | |
| 192 | def on_import_tabs_switch_page(self, notebook, page, page_num): |
| 193 | self.importgui.show_importpane(notebook, page_num)
|
| 194 | |
| 195 | def on_button_template_ok_clicked(self, button, data=None): |
| 196 | template = self.template_doc.get_template()
|
| 197 | if template is not None: |
| 198 | self.editorpane.fill_buffer(template)
|
| 199 | self.filename = None |
| 200 | self.iofunc.make_environment(self.filename) |
| 201 | self.template_doc.templatewindow.hide()
|
| 202 | else: pass |
| 203 | |
| 204 | def on_button_template_cancel_clicked(self, button, data=None): |
| 205 | self.template_doc.templatewindow.hide()
|
| 206 | return True |
| 207 | |
| 208 | def on_menu_bibupdate_activate(self, menuitem, data=None): |
| 209 | self.biblio.compile_bibliography()
|
| 210 | |
| 211 | def on_bibprogressbar_update(self): |
| 212 | self.bibprogressmon.set_value(self.bibprogressval) |
| 213 | self.bibprogressval = self.bibprogressval + 1 |
| 214 | if self.bibprogressval > 60: |
| 215 | return False |
| 216 | else:
|
| 217 | return True |
| 218 | |
| 219 | def on_bibrefresh_clicked(self, button, data=None): |
| 220 | self.bibprogressval = 0 |
| 221 | glib.timeout_add(2, self.on_bibprogressbar_update) |
| 222 | self.list_biblios.clear()
|
| 223 | bibfilenm = self.builder.get_object("bibfilenm") |
| 224 | bibrefnr = self.builder.get_object("bibrefnr") |
| 225 | if self.biblio.detect_bibliography(): |
| 226 | filenm, number = self.biblio.setup_bibliography()
|
| 227 | number = self.biblio.parse_entries(self.list_biblios) |
| 228 | bibfilenm.set_text(filenm) |
| 229 | bibrefnr.set_text(str(number))
|
| 230 | self.bibprogressbar.set_text(filenm + " loaded") |
| 231 | else:
|
| 232 | self.bibprogressbar.set_text("no bibliography file detected") |
| 233 | bibfilenm.set_text("None")
|
| 234 | bibrefnr.set_text("N/A")
|
| 235 | |
| 236 | def on_bibcompile_clicked(self, button, data=None): |
| 237 | self.bibprogressval = 0 |
| 238 | glib.timeout_add(10, self.on_bibprogressbar_update) |
| 239 | if self.biblio.compile_bibliography(self.bibprogressbar): |
| 240 | self.iofunc.set_status("Compiling bibliography file..") |
| 241 | self.bibprogressbar.set_text("bibliography compiled without errors") |
| 242 | else:
|
| 243 | self.iofunc.set_status("Error compiling bibliography file or none detected..") |
| 244 | self.bibprogressbar.set_text("error compiling bibliography file") |
| 245 | |
| 246 | |
| 247 | |
| 248 | def on_menu_bibload_activate(self, menuitem, data=None): |
| 249 | bibfile = None
|
| 250 | chooser = gtk.FileChooserDialog("Open File...", self.mainwindow, |
| 251 | gtk.FILE_CHOOSER_ACTION_OPEN, |
| 252 | (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, |
| 253 | gtk.STOCK_OPEN, gtk.RESPONSE_OK)) |
| 254 | bibfilter = gtk.FileFilter() |
| 255 | bibfilter.set_name('Bibtex files')
|
| 256 | bibfilter.add_pattern("*.bib")
|
| 257 | chooser.add_filter(bibfilter) |
| 258 | response = chooser.run() |
| 259 | if response == gtk.RESPONSE_CANCEL: return |
| 260 | if response == gtk.RESPONSE_OK:
|
| 261 | bibfile = chooser.get_filename() |
| 262 | if self.biblio.check_valid_file(bibfile): |
| 263 | filenm, number = self.biblio.setup_bibliography()
|
| 264 | bibfilenm = self.builder.get_object("bibfilenm") |
| 265 | bibfilenm.set_text(filenm) |
| 266 | chooser.destroy() |
| 267 | |
| 268 | def on_bibcolumn_clicked(self, item, data=None): |
| 269 | sortid = item.get_sort_column_id() |
| 270 | item.set_sort_column_id(sortid) |
| 271 | |
| 272 | def on_bibreference_clicked(self, item, event, data=None): |
| 273 | selection = item.get_selection() |
| 274 | myiter = selection.get_selected()[1]
|
| 275 | value = self.list_biblios.get_value(myiter, 0) |
| 276 | self.editorpane.editorbuffer.insert_at_cursor("\cite{" + value + "}") |
| 277 | self.editorpane.set_buffer_changed()
|
| 278 | |
| 279 | def on_menu_preferences_activate(self, menuitem, data=None): |
| 280 | prefsgui = PrefsGUI(self.config, self.editorpane, self.path, self.mainwindow, self.iofunc) |
| 281 | |
| 282 | def on_menu_update_activate(self, menuitem, data=None): |
| 283 | update = UpdateCheck.UpdateCheck() |
| 284 | |
| 285 | def on_menu_about_activate(self, menuitem, data=None): |
| 286 | authors = ["Alexander van der Mey\n<alexvandermey@gmail.com>\n\n"
|
| 287 | "Contributors:\n"
|
| 288 | "Thomas van der Burgt <thomas@thvdburgt.nl>\n"
|
| 289 | "Cameron Grout <camerongrout@gmail.com>\n"]
|
| 290 | artwork = ["Template icon set from:\nhttp://www.fatcow.com/free-icons/"]
|
| 291 | about_dialog = gtk.AboutDialog() |
| 292 | about_dialog.set_transient_for(self.mainwindow)
|
| 293 | about_dialog.set_destroy_with_parent(True)
|
| 294 | about_dialog.set_name("Gummi")
|
| 295 | about_dialog.set_license(Preferences.LICENSE) |
| 296 | about_dialog.set_version(Preferences.VERSION) |
| 297 | about_dialog.set_copyright("Copyright \xc2\xa9 2009 Alexander van der Mey")
|
| 298 | about_dialog.set_website("http://gummi.midnightcoding.org")
|
| 299 | about_dialog.set_comments("Simple LaTeX Editor for GTK+ users")
|
| 300 | about_dialog.set_authors(authors) |
| 301 | about_dialog.set_artists(artwork) |
| 302 | about_dialog.set_logo_icon_name (gtk.STOCK_EDIT) |
| 303 | # callbacks for destroying the dialog
|
| 304 | def close(dialog, response, editor): |
| 305 | editor.about_dialog = None
|
| 306 | dialog.destroy() |
| 307 | def delete_event(dialog, event, editor): |
| 308 | editor.about_dialog = None
|
| 309 | return True |
| 310 | about_dialog.connect("response", close, self) |
| 311 | about_dialog.connect("delete-event", delete_event, self) |
| 312 | self.about_dialog = about_dialog
|
| 313 | about_dialog.show() |
| 314 | |
| 315 | def on_tool_textstyle_activate(self, button, data=None): |
| 316 | self.editorpane.set_selection_textstyle(button)
|
| 317 | |
| 318 | def on_button_import_apply_clicked(self, button, data=None): |
| 319 | self.importgui.insert_object(button)
|
| 320 | |
| 321 | def on_image_file_activate(self, button, event, data=None): |
| 322 | self.importgui.choose_imagefile()
|
| 323 | |
| 324 | def on_button_pageback_clicked(self, button, data=None): |
| 325 | self.previewpane.jump_to_prevpage()
|
| 326 | |
| 327 | def on_button_pageforward_clicked(self, button, data=None): |
| 328 | self.previewpane.jump_to_nextpage()
|
| 329 | |
| 330 | def on_button_zoomin_clicked(self, button, data=None): |
| 331 | self.previewpane.zoom_in_pane()
|
| 332 | |
| 333 | def on_button_zoomout_clicked(self, button, data=None): |
| 334 | self.previewpane.zoom_out_pane()
|
| 335 | |
| 336 | def on_button_bestfit_toggled(self, button, data=None): |
| 337 | if button.get_active() == False: |
| 338 | self.previewpane.set_bestfitmode(False) |
| 339 | else:
|
| 340 | self.previewpane.set_bestfitmode(True) |
| 341 | |
| 342 | def on_button_bibadd_clicked(self, button, data=None): |
| 343 | self.biblio.add_bibliography()
|
| 344 | |
| 345 | def on_button_bibdel_clicked(self, button, data=None): |
| 346 | self.biblio.del_bibliography()
|
| 347 | |
| 348 | def on_button_bibapply_clicked(self, button, data=None): |
| 349 | self.biblio.setup_bibliography()
|
| 350 | self.mainnotebook.set_current_page(0) |
| 351 | |
| 352 | def set_file_filters(self, dialog): |
| 353 | plainfilter = gtk.FileFilter() |
| 354 | plainfilter.set_name('Text files')
|
| 355 | plainfilter.add_mime_type("text/plain")
|
| 356 | dialog.add_filter(plainfilter) |
| 357 | |
| 358 | latexfilter = gtk.FileFilter() |
| 359 | latexfilter.set_name('LaTeX files')
|
| 360 | latexfilter.add_pattern('*.tex')
|
| 361 | dialog.add_filter(latexfilter) |
| 362 | dialog.set_filter(plainfilter) |
| 363 | |
| 364 | def get_open_filename(self): |
| 365 | filename = None
|
| 366 | chooser = gtk.FileChooserDialog("Open File...", self.mainwindow, |
| 367 | gtk.FILE_CHOOSER_ACTION_OPEN, |
| 368 | (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, |
| 369 | gtk.STOCK_OPEN, gtk.RESPONSE_OK)) |
| 370 | self.set_file_filters(chooser)
|
| 371 | |
| 372 | response = chooser.run() |
| 373 | if response == gtk.RESPONSE_OK: filename = chooser.get_filename()
|
| 374 | chooser.destroy() |
| 375 | return filename
|
| 376 | |
| 377 | def get_save_filename(self): |
| 378 | filename = None
|
| 379 | chooser = gtk.FileChooserDialog("Save File...", self.mainwindow, |
| 380 | gtk.FILE_CHOOSER_ACTION_SAVE, |
| 381 | (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, |
| 382 | gtk.STOCK_SAVE, gtk.RESPONSE_OK)) |
| 383 | self.set_file_filters(chooser)
|
| 384 | response = chooser.run() |
| 385 | if response == gtk.RESPONSE_CANCEL:
|
| 386 | self.exitinterrupt = True |
| 387 | return
|
| 388 | if response == gtk.RESPONSE_OK:
|
| 389 | filename = chooser.get_filename() |
| 390 | if not ".tex" in filename[-4:]: |
| 391 | filename = filename + ".tex"
|
| 392 | chooser.destroy() |
| 393 | self.iofunc.make_environment(filename)
|
| 394 | chooser.destroy() |
| 395 | return filename
|
| 396 | |
| 397 | def check_for_save(self): |
| 398 | ret = False
|
| 399 | if self.editorpane.editorbuffer.get_modified(): |
| 400 | # we need to prompt for save
|
| 401 | message = "Do you want to save the changes you have made?"
|
| 402 | dialog = gtk.MessageDialog(self.mainwindow,
|
| 403 | gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, |
| 404 | gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, |
| 405 | message) |
| 406 | dialog.set_title("Save?")
|
| 407 | if dialog.run() == gtk.RESPONSE_NO: ret = False |
| 408 | else: ret = True |
| 409 | dialog.destroy() |
| 410 | return ret
|
| 411 | |
| 412 | |
| 413 | def load_document(self, filename): |
| 414 | while gtk.events_pending(): gtk.main_iteration()
|
| 415 | try:
|
| 416 | self.iofunc.load_file(filename)
|
| 417 | self.filename = filename
|
| 418 | self.recentgui.add_recentfile(self.filename) |
| 419 | self.set_window_title(self.filename) |
| 420 | except:
|
| 421 | print traceback.print_exc()
|
| 422 | |
| 423 | |
| 424 | def save_document(self, filename): |
| 425 | try:
|
| 426 | self.iofunc.save_file(filename)
|
| 427 | if filename: self.filename = filename |
| 428 | self.iofunc.set_status("Saving file " + self.filename) |
| 429 | self.iofunc.export_pdffile()
|
| 430 | self.set_window_title(self.filename) |
| 431 | except:
|
| 432 | print traceback.print_exc()
|
| 433 | |
| 434 | |
| 435 | def gtk_main_quit(self, menuitem, data=None): |
| 436 | if self.check_for_save(): self.on_menu_save_activate(None, None) |
| 437 | if self.exitinterrupt is False: |
| 438 | print " ___ " |
| 439 | print " {o,o} Thanks for using Gummi!" |
| 440 | print " |)__) I welcome your feedback at:" |
| 441 | print ' -"-"- http://gummi.midnightcoding.org\n' |
| 442 | quit() |
| 443 | else: self.exitinterrupt = False; return True |
| 444 | |
| 445 | |
| 446 | |
| 447 | class PrefsGUI: |
| 448 | |
| 449 | def __init__(self, config, editorpane, path, mainwindow, iofunc): |
| 450 | self.config = config
|
| 451 | self.editorpane = editorpane
|
| 452 | self.iofunc = iofunc
|
| 453 | builder = gtk.Builder() |
| 454 | builder.add_from_file(path + "/gui/prefs.glade")
|
| 455 | |
| 456 | self.prefwindow = builder.get_object("prefwindow") |
| 457 | self.notebook = builder.get_object("notebook1") |
| 458 | self.prefwindow.set_transient_for(mainwindow)
|
| 459 | self.textwrap_button = builder.get_object("textwrapping") |
| 460 | self.wordwrap_button = builder.get_object("wordwrapping") |
| 461 | self.autosave_timer = builder.get_object("autosave_timer") |
| 462 | self.default_text = builder.get_object("default_text") |
| 463 | self.default_text.modify_font(pango.FontDescription("monospace 10")) |
| 464 | self.default_buffer = self.default_text.get_buffer() |
| 465 | self.typesetter = builder.get_object("combo_typesetter") |
| 466 | self.editor_font = builder.get_object("editor_font") |
| 467 | |
| 468 | self.view_box = builder.get_object("view_box") |
| 469 | self.set_checkbox_status(self.view_box, 'view') |
| 470 | self.editor_box = builder.get_object("editor_box") |
| 471 | self.set_checkbox_status(self.editor_box, 'editor') |
| 472 | self.autosave_timer.set_value \
|
| 473 | (int(self.config.get_value("editor", "autosave_timer"))/60) |
| 474 | self.editor_font.set_font_name(self.config.get_value("editor", "font")) |
| 475 | self.default_buffer.set_text \
|
| 476 | (self.config.get_value("default_text", "welcome")) |
| 477 | if self.config.get_value("compile", "typesetter") == "xelatex": |
| 478 | self.typesetter.set_active(1) |
| 479 | |
| 480 | builder.connect_signals(self)
|
| 481 | self.prefwindow.show_all()
|
| 482 | |
| 483 | |
| 484 | def set_checkbox_status(self, box, page): |
| 485 | listmy = box.get_children() |
| 486 | for item in listmy: |
| 487 | if type(item) == gtk.CheckButton: |
| 488 | result = self.config.get_value(page, item.get_name())
|
| 489 | item.set_active(result) |
| 490 | |
| 491 | def toggle_linenumbers(self, widget, data=None): |
| 492 | value = widget.get_active() |
| 493 | self.config.set_value('view', widget.get_name(), value) |
| 494 | self.editorpane.editorviewer.set_show_line_numbers(value)
|
| 495 | |
| 496 | def toggle_highlighting(self, widget, data=None): |
| 497 | value = widget.get_active() |
| 498 | self.config.set_value('view', widget.get_name(), value) |
| 499 | self.editorpane.editorviewer.set_highlight_current_line(value)
|
| 500 | |
| 501 | def toggle_textwrapping(self, widget, data=None): |
| 502 | value = widget.get_active() |
| 503 | self.config.set_value('view', widget.get_name(), value) |
| 504 | if widget.get_active():
|
| 505 | self.editorpane.editorviewer.set_wrap_mode(gtk.WRAP_CHAR)
|
| 506 | self.wordwrap_button.set_sensitive(True) |
| 507 | else:
|
| 508 | self.editorpane.editorviewer.set_wrap_mode(gtk.WRAP_NONE)
|
| 509 | self.config.set_value("view", "wordwrapping", False) |
| 510 | self.wordwrap_button.set_active(False) |
| 511 | self.wordwrap_button.set_sensitive(False) |
| 512 | |
| 513 | def toggle_wordwrapping(self, widget, data=None): |
| 514 | value = widget.get_active() |
| 515 | self.config.set_value('view', widget.get_name(), value) |
| 516 | if widget.get_active():
|
| 517 | self.editorpane.editorviewer.set_wrap_mode(gtk.WRAP_WORD)
|
| 518 | else:
|
| 519 | self.editorpane.editorviewer.set_wrap_mode(gtk.WRAP_CHAR)
|
| 520 | |
| 521 | def toggle_autosaving(self, widget, data=None): |
| 522 | value = widget.get_active() |
| 523 | self.config.set_value('editor', widget.get_name(), value) |
| 524 | if widget.get_active():
|
| 525 | self.autosave_timer.set_sensitive(True) |
| 526 | time = int(self.config.get_value("editor", "autosave_timer")) |
| 527 | self.autosave_timer.set_value(time/60) |
| 528 | self.iofunc.start_autosave(time)
|
| 529 | else:
|
| 530 | self.autosave_timer.set_sensitive(False) |
| 531 | self.iofunc.stop_autosave()
|
| 532 | |
| 533 | def on_autosave_value_changed(self, event): |
| 534 | newvalue = int(event.get_value()) * 60 |
| 535 | self.config.set_value('editor', 'autosave_timer', newvalue) |
| 536 | self.iofunc.reset_autosave()
|
| 537 | |
| 538 | def on_editor_font_set(self, widget): |
| 539 | selected = widget.get_font_name() |
| 540 | self.editorpane.editorviewer.modify_font(pango.FontDescription(selected))
|
| 541 | self.config.set_value("editor", "font", selected) |
| 542 | |
| 543 | def on_combo_typesetter_changed(self, widget, data=None): |
| 544 | model = widget.get_model() |
| 545 | newvalue = model[widget.get_active()][0]
|
| 546 | self.config.set_value('compile', 'typesetter', newvalue) |
| 547 | |
| 548 | def on_prefs_close_clicked(self, widget, data=None): |
| 549 | if self.notebook.get_current_page() == 2: |
| 550 | start_iter = self.default_buffer.get_start_iter()
|
| 551 | end_iter = self.default_buffer.get_end_iter()
|
| 552 | newvalue = self.default_buffer.get_text(start_iter, end_iter)
|
| 553 | self.config.set_value("default_text", "welcome", newvalue) |
| 554 | self.prefwindow.destroy()
|
| 555 | |
| 556 | def on_prefs_reset_clicked(self, widget, data=None): |
| 557 | if self.notebook.get_current_page() == 0: |
| 558 | self.config.reset_section("view") |
| 559 | self.set_checkbox_status(self.view_box, "view") |
| 560 | elif self.notebook.get_current_page() == 1: |
| 561 | self.config.reset_section("editor") |
| 562 | self.set_checkbox_status(self.editor_box, "editor") |
| 563 | deffont = self.config.get_value("editor", "font") |
| 564 | self.editor_font.set_font_name(deffont)
|
| 565 | self.editorpane.editorviewer.modify_font(pango.FontDescription(deffont))
|
| 566 | elif self.notebook.get_current_page() == 2: |
| 567 | self.config.reset_section("default_text") |
| 568 | self.default_buffer.set_text \
|
| 569 | (self.config.get_value("default_text", "welcome")) |
| 570 | elif self.notebook.get_current_page() == 3: |
| 571 | self.config.reset_section("compile") |
| 572 | self.typesetter.set_active(0) |
| 573 | |
| 574 | |
| 575 | |
| 576 | class SearchGUI: |
| 577 | |
| 578 | def __init__(self, builder, editorpane): |
| 579 | self.builder = builder
|
| 580 | self.editorpane = editorpane
|
| 581 | self.setup_searchwindow()
|
| 582 | |
| 583 | def setup_searchwindow(self): |
| 584 | self.searchwindow = self.builder.get_object("searchwindow") |
| 585 | self.searchentry = self.builder.get_object("searchentry") |
| 586 | self.backwards = self.builder.get_object("toggle_backwards") |
| 587 | self.matchcase = self.builder.get_object("toggle_matchcase") |
| 588 | self.wholeword = self.builder.get_object("toggle_wholeword") |
| 589 | |
| 590 | def show_searchwindow(self): |
| 591 | self.searchentry.set_text("") |
| 592 | self.searchentry.grab_focus()
|
| 593 | self.searchwindow.show()
|
| 594 | |
| 595 | def close_searchwindow(self): |
| 596 | self.searchwindow.hide()
|
| 597 | return True |
| 598 | |
| 599 | def start_search(self): |
| 600 | term = self.searchentry.get_text()
|
| 601 | backwards = self.backwards.get_active()
|
| 602 | matchcase = self.matchcase.get_active()
|
| 603 | wholeword = self.wholeword.get_active()
|
| 604 | self.editorpane.start_search(term, backwards, wholeword, matchcase)
|
| 605 | |
| 606 | |
| 607 | class ImportGUI: |
| 608 | |
| 609 | def __init__(self, builder, editorpane): |
| 610 | self.builder = builder
|
| 611 | self.editorpane = editorpane
|
| 612 | self.setup_importpanes()
|
| 613 | |
| 614 | def setup_importpanes(self): |
| 615 | self.box_image = self.builder.get_object("box_image") |
| 616 | self.box_table = self.builder.get_object("box_table") |
| 617 | self.box_matrix = self.builder.get_object("box_matrix") |
| 618 | self.image_pane = self.builder.get_object("image_pane") |
| 619 | self.table_pane = self.builder.get_object("table_pane") |
| 620 | self.matrix_pane = self.builder.get_object("matrix_pane") |
| 621 | self.importer = Importer.Importer(self.editorpane, self.builder) |
| 622 | |
| 623 | def show_importpane(self, notebook, page_num): |
| 624 | newactive = notebook.get_nth_page(page_num).get_name() |
| 625 | self.box_image.foreach(lambda x:self.box_image.remove(x)) |
| 626 | self.box_table.foreach(lambda x:self.box_table.remove(x)) |
| 627 | self.box_matrix.foreach(lambda x:self.box_matrix.remove(x)) |
| 628 | if newactive == "box_image": |
| 629 | self.box_image.add(self.image_pane) |
| 630 | elif newactive == "box_table": |
| 631 | self.box_table.add(self.table_pane) |
| 632 | elif newactive == "box_matrix": |
| 633 | self.box_matrix.add(self.matrix_pane) |
| 634 | |
| 635 | def insert_object(self, widget): |
| 636 | caller = widget.get_name() |
| 637 | if caller == "table_apply": |
| 638 | self.importer.insert_table()
|
| 639 | elif caller == "image_apply": |
| 640 | self.importer.insert_image()
|
| 641 | elif caller == "matrix_apply": |
| 642 | self.importer.insert_matrix()
|
| 643 | |
| 644 | def choose_imagefile(self): |
| 645 | self.importer.prepare_image()
|
| 646 | |
| 647 | |
| 648 | |
| 649 | |
| 650 | class RecentGUI: |
| 651 | |
| 652 | def __init__(self, builder, config, parent): |
| 653 | self.builder = builder
|
| 654 | self.config = config
|
| 655 | self.parent = parent
|
| 656 | self.iofunc = self.parent.iofunc |
| 657 | |
| 658 | self.recentlist = []
|
| 659 | self.setup_recentfiles()
|
| 660 | |
| 661 | |
| 662 | def setup_recentfiles(self): |
| 663 | self.recent1 = self.builder.get_object("menu_recent1") |
| 664 | self.recent2 = self.builder.get_object("menu_recent2") |
| 665 | self.recent3 = self.builder.get_object("menu_recent3") |
| 666 | recent1 = self.config.get_value("recent_files", "recent1") |
| 667 | recent2 = self.config.get_value("recent_files", "recent2") |
| 668 | recent3 = self.config.get_value("recent_files", "recent3") |
| 669 | self.recentlist.append(recent1)
|
| 670 | self.recentlist.append(recent2)
|
| 671 | self.recentlist.append(recent3)
|
| 672 | self.display_recentfile(0, self.recent1) |
| 673 | self.display_recentfile(1, self.recent2) |
| 674 | self.display_recentfile(2, self.recent3) |
| 675 | |
| 676 | def display_recentfile(self, i, widget): |
| 677 | try:
|
| 678 | if not self.recentlist[i] == "": |
| 679 | entry = os.path.basename(self.recentlist[i])
|
| 680 | widget.get_children()[0].set_label(str(i+1) + ". " + entry) |
| 681 | widget.show() |
| 682 | except IndexError: widget.hide() |
| 683 | |
| 684 | def activate_recentfile(self, widget): |
| 685 | indexstr = widget.get_name()[11:] # dirty hack |
| 686 | indexnr = int(indexstr)-1 # to get index number |
| 687 | if os.path.exists(self.recentlist[indexnr]): |
| 688 | self.load_recentfile(self.recentlist[indexnr]) |
| 689 | else:
|
| 690 | self.remove_recentfile(indexnr)
|
| 691 | |
| 692 | def add_recentfile(self, filename): |
| 693 | if filename not in self.recentlist: |
| 694 | self.recentlist.insert(0, filename) |
| 695 | if len(self.recentlist) > 3: |
| 696 | del self.recentlist[3] |
| 697 | for index,value in enumerate(self.recentlist): |
| 698 | position = str(index+1) |
| 699 | self.config.set_value \
|
| 700 | ("recent_files", "recent" + position, value) |
| 701 | self.display_recentfile(0, self.recent1) |
| 702 | self.display_recentfile(1, self.recent2) |
| 703 | self.display_recentfile(2, self.recent3) |
| 704 | |
| 705 | |
| 706 | def remove_recentfile(self, position): |
| 707 | self.iofunc.set_status("Error loading recent file: " + str(self.recentlist[position])) |
| 708 | self.recentlist.pop(position)
|
| 709 | for index,value in enumerate(self.recentlist): |
| 710 | position = str(index+1) |
| 711 | self.config.set_value("recent_files", "recent" + position, value) |
| 712 | self.display_recentfile(0, self.recent1) |
| 713 | self.display_recentfile(1, self.recent2) |
| 714 | self.display_recentfile(2, self.recent3) |
| 715 | |
| 716 | |
| 717 | def load_recentfile(self, filename): |
| 718 | self.parent.check_for_save()
|
| 719 | self.parent.load_document(filename)
|
| 720 |