gwrite-0.5.1/0000755000175000017500000000000011534726513011505 5ustar aronarongwrite-0.5.1/AUTHORS0000644000175000017500000000015111534726454012556 0ustar aronaronMain Developer: Jiahua Huang Other Developer: Aron Xu gwrite-0.5.1/COPYING0000644000175000017500000001672511534726454012557 0ustar aronaron GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. gwrite-0.5.1/ChangeLog0000644000175000017500000000065211534726454013266 0ustar aronaron2011-03-06 Jiahua Huang * Release gwrite-0.5.1 2010-02-02 Aron Xu * Release gwrite-0.2.0 2010-01-26 Aron Xu * Release gwrite-0.1.4 2010-01-26 Aron Xu * Release gwrite-0.1.3 2010-01-02 Aron Xu * Release gwrite-0.1.2 2010-01-02 Aron Xu * Release gwrite-0.1.1 gwrite-0.5.1/MANIFEST.in0000644000175000017500000000037411534726454013253 0ustar aronaroninclude COPYING ChangeLog AUTHORS README include install include *.in *.py *.png *.sh *.cmd *.cfg recursive-include script * recursive-include gwrite *.js *.html *.htm *.png *.gif *.jpg *.py *.txt *.xml *.in *.conf *.ui recursive-include po *.po *.in gwrite-0.5.1/TODO0000644000175000017500000000124611534726454012204 0ustar aronaron +0. 解决 Webkit 无法跳转到 #锚点 的问题 +1. 用 webkit 换掉 gtkmozembed +2. 文件菜单添加 文档字数 等统计信息 +3. 增加工具栏 +4. 增加右侧栏 文档结构图 -5. 取消多窗口,改为新文档使用新进程 =6. 修改 setup.py 的 po 翻译文件处理 +7. 增加修改保存提示 +8. 增加插入、编辑 LaTex 数学公式 用 script-prompt 事件支持双击编辑公式 8.1 右键菜单添加编辑公式 +9. 修复 maverick 下丢失 stock 图标 因为 ubuntu 10.10 的 gnome-icons 去掉了 stock_insert_image,stock_view-html-source 等图标 所以将用到的图标放到 gwrite/icons 下 gwrite-0.5.1/gwrite.desktop.in0000644000175000017500000000033411534726454015012 0ustar aronaron[Desktop Entry] Name=GWrite Name[zh_CN]=写字板 Comment=Simple text editor Comment[zh_CN]=HTML 写字板 Exec=gwrite %f Icon=gwrite Terminal=false Type=Application MimeType=text/html Categories=GTK;Utility;TextEditor; gwrite-0.5.1/gwrite.png0000644000175000017500000000250511534726454013522 0ustar aronaronPNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATXWkoe~^mw vK JbF1JRD DbjhTZ Tc!JiWn\; gwg9<ϙYbf@nrb(o9͸BܖR?pff3,Kya|k|Hwpao*.Q*680FM5 hn8v-4bB8 "R,F$DH@Yi0M}{_I(r:791P{@u16QD"XL&at=AT _ mmm04Mˉ&_Uj$ĸ2KAy".  $ 03A |GUH@H'G2noIKpn3v2BHFGG[>R0`\B!Z[ZКLL5`f Kih3R X>.`[ڵSGBudޱJs- YXſb L-#p/4U)q0N#JJF!Vη u uf!% N]kRz|`,׳gO{znU/#Ǿ6#+&>,ݲ`p "|+ŕ DQg %#Up-{! - XT_9 ƞ4yI0P֘%0\2!sBT ."twe=ίfdmM5ˠ"bƅh cƇ6% wxǴ MdPTM,XvsUlty ܩ@4COw> ޛ3aΌ7l ?_=Չ;:HrAC X.`*[ A"Zgu"/kT sP\-_BQd{\ u8.aT @3uEHDd}Vqa`%/j1"p|?7Sw5pC**cJ @Ji0RTk'#[L-ϱ !*PHOw/#"WP(4[@UWǧ8FӚ{4+ߪs_&'e}IENDB`gwrite-0.5.1/gwrite/0000755000175000017500000000000011534726454013012 5ustar aronarongwrite-0.5.1/gwrite/__init__.py0000644000175000017500000000000011534726454015111 0ustar aronarongwrite-0.5.1/gwrite/config.py0000644000175000017500000001031411534726454014630 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- '''config @author: U{Jiahua Huang } @license: LGPLv3+ ''' import gtk, gobject import os, sys try: import cPickle as pickle except: import pickle try: import i18n except: from gettext import gettext as _ single_instance_mode = 0 mdi_mode = 1 def getconf(): '''获取 config ''' config = {} ## profdir = os.environ['HOME'] + '/.config/GWrite' if not os.path.isdir(profdir): os.makedirs(profdir) ctlfile = profdir + '/gwrite.ctl' + os.environ['DISPLAY'] prof = profdir + '/gwrite.conf' user_stylesheet_file = profdir + '/user_stylesheet_uri.css' ## for k, v in globals().items(): if not k.startswith('__') and ( isinstance(v, str) or isinstance(v, int) or isinstance(v, long) or isinstance(v, float) or isinstance(v, dict) or isinstance(v, list) or isinstance(v, bool) ): config[k] = v pass config['profdir'] = profdir config['ctlfile'] = ctlfile config['prof'] = prof config['user_stylesheet_file'] = user_stylesheet_file return config def load(): '''读取 config ''' config = getconf() ## try: config.update(pickle.loads(file(config['prof']).read())) except: pass ## globals().update(config) return config def write(): '''保存 config ''' config = getconf() file(config['prof'], 'w').write(pickle.dumps(config)) return config def show_preference_dlg(title=_("Preferences"), parent=None, *args): '''首选项对话框 ''' dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) dlg.set_default_size(200, 300) ## config = getconf() ## notebook1 = gtk.Notebook() notebook1.set_tab_pos(gtk.POS_TOP) notebook1.set_scrollable(False) notebook1.show() vbox1 = gtk.VBox(False, 0) vbox1.show() vbox1.set_spacing(0) checkbutton_mdi_mode = gtk.CheckButton() checkbutton_mdi_mode.set_active(False) checkbutton_mdi_mode.set_label(_("Use Tabs MDI interface")) checkbutton_mdi_mode.set_tooltip_text(_("Supports editing multiple files in one window (known sometimes as tabs or MDI)")) checkbutton_mdi_mode.show() checkbutton_mdi_mode.set_border_width(10) checkbutton_mdi_mode.set_relief(gtk.RELIEF_NORMAL) vbox1.pack_start(checkbutton_mdi_mode, False, False, 0) checkbutton_single_instance_mode = gtk.CheckButton() checkbutton_single_instance_mode.set_active(False) checkbutton_single_instance_mode.set_label(_("Single Instance mode")) checkbutton_single_instance_mode.set_tooltip_text(_("Only one instance of the application will be running at a time.")) checkbutton_single_instance_mode.show() checkbutton_single_instance_mode.set_border_width(10) checkbutton_single_instance_mode.set_relief(gtk.RELIEF_NORMAL) vbox1.pack_start(checkbutton_single_instance_mode, False, False, 0) hseparator1 = gtk.HSeparator() hseparator1.show() vbox1.pack_start(hseparator1, False, False, 0) label2 = gtk.Label(_("You need to restart gwrite for some options to take effect.")) label2.set_alignment(0, 0) label2.set_angle(0) label2.set_padding(20, 20) label2.set_line_wrap(True) label2.set_width_chars(30) label2.show() vbox1.pack_start(label2) label1 = gtk.Label(_("Run mode")) label1.set_angle(0) label1.set_padding(0, 0) label1.set_line_wrap(False) label1.show() notebook1.append_page(vbox1, label1) ## checkbutton_mdi_mode.set_active(config.get("mdi_mode", 0)) checkbutton_single_instance_mode.set_active(config.get("single_instance_mode", 0)) ## dlg.vbox.pack_start(notebook1, True, True, 0) resp = dlg.run() ## config['mdi_mode'] = checkbutton_mdi_mode.get_active() config['single_instance_mode'] = checkbutton_single_instance_mode.get_active() ## dlg.destroy() if resp == gtk.RESPONSE_CANCEL: return {} globals().update(config) return config if __name__=="__main__": load() print show_preference_dlg() write() gwrite-0.5.1/gwrite/docfilter.py0000644000175000017500000000105611534726454015341 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: # Author: Huang Jiahua # License: LGPLv3+ # Last modified: '''文档格式转换 ''' import os import subprocess def doc2html(docfile): '''将 mso doc 转换为 html 依赖 wv ''' dir = os.tmpnam() dir = dir.replace('file', 'gwrite-%s/file' % os.getlogin() ) html = 'gwrite.html' os.makedirs(dir) subprocess.Popen(['wvHtml', '--targetdir=%s'%dir, docfile, html]).wait() return dir + '/' + html gwrite-0.5.1/gwrite/gtkdialogs.py0000755000175000017500000004016011534726454015520 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- '''Gtk 对话框 @author: U{Jiahua Huang } @license: LGPLv3+ ''' import os import gtk import gobject __all__ = ['error', 'info', 'inputbox', 'messagedialog', 'open', 'save', 'warning', 'yesno'] try: import i18n except: from gettext import gettext as _ def colorbox(title="Changing color", previous_color='', current_color=''): ''' ''' dialog = gtk.ColorSelectionDialog("Changing color") colorsel = dialog.colorsel if current_color: colorsel.set_previous_color(previous_color) if current_color: colorsel.set_current_color(current_color) colorsel.set_has_palette(True) response = dialog.run() htmlcolor = '' if response == gtk.RESPONSE_OK: color = colorsel.get_current_color() rgb = (color.red, color.green, color.blue) htmlcolor = '#' + ''.join((str(hex(i/257))[2:].rjust(2, '0') for i in rgb)) dialog.destroy() return htmlcolor def textbox(title='Text Box', label='Text', parent=None, text=''): """display a text edit dialog return the text , or None """ dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) dlg.set_default_size(500,500) #lbl = gtk.Label(label) #lbl.set_alignment(0, 0.5) #lbl.show() #dlg.vbox.pack_start(lbl, False) gscw = gtk.ScrolledWindow() gscw.set_shadow_type(gtk.SHADOW_IN) #gscw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) gscw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) textview=gtk.TextView(buffer=None) buffer = textview.get_buffer() if text:buffer.set_text(text) #textview.show() gscw.add(textview) #gscw.show() dlg.vbox.pack_start(gscw) dlg.show_all() resp = dlg.run() text=buffer.get_text(buffer.get_start_iter(),buffer.get_end_iter()) dlg.destroy() if resp == gtk.RESPONSE_OK: return text return None def combobox(title='ComboBox', label='ComboBox', parent=None, texts=['']): '''dialog with combobox ''' dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) label1 = gtk.Label(label) label1.set_alignment(0, 0.5) label1.set_padding(5, 5) label1.set_line_wrap(True) label1.show() dlg.vbox.pack_start(label1, False, False, 0) combobox1_List = gtk.ListStore(gobject.TYPE_STRING) combobox1 = gtk.ComboBox() combobox1.show() #combobox1_List.append(["1122"]) combobox1.set_model(combobox1_List) cell = gtk.CellRendererText() combobox1.pack_start(cell, True) combobox1.add_attribute(cell, 'text', 0) dlg.vbox.pack_start(combobox1, True, True, 0) for i in texts: combobox1.append_text(i) combobox1.set_active(0) resp = dlg.run() t = combobox1.get_active() text = texts[t] dlg.destroy() if resp == gtk.RESPONSE_CANCEL: return None return text def spinbox2(title='2 Spin Box', label1='value1:', label2='value2:', parent=None, value1=3, value2=3): """dialog with 2 spin buttons return (value1,value2) , or () """ dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) lbl = gtk.Label(title) lbl.set_alignment(0, 0.5) dlg.vbox.pack_start(lbl, False) #vbox1 = gtk.VBox(False, 0) #vbox1.show() #vbox1.set_spacing(0) table2 = gtk.Table() table2.show() table2.set_row_spacings(0) table2.set_col_spacings(0) label1 = gtk.Label(label1) label1.set_alignment(0, 0.5) label1.set_padding(0, 0) label1.set_line_wrap(False) label1.show() table2.attach(label1, 0, 1, 0, 1, gtk.FILL, 0, 0, 0) label2 = gtk.Label(label2) label2.set_alignment(0, 0.5) label2.set_padding(0, 0) label2.set_line_wrap(False) label2.show() table2.attach(label2, 0, 1, 1, 2, gtk.FILL, 0, 0, 0) adj = gtk.Adjustment(1.0, 1.0, 512.0, 1.0, 5.0, 0.0) spin1=gtk.SpinButton(adj,0,0) if value1: spin1.set_value(value1) table2.attach(spin1, 1, 2, 0, 1, gtk.EXPAND|gtk.FILL, 0, 0, 0) adj2 = gtk.Adjustment(1.0, 1.0, 512.0, 1.0, 5.0, 0.0) spin2=gtk.SpinButton(adj2,0,0) if value2: spin2.set_value(value2) table2.attach(spin2, 1, 2, 1, 2, gtk.EXPAND|gtk.FILL, 0, 0, 0) #vbox1.pack_start(table2, True, True, 0) dlg.vbox.pack_start(table2) dlg.show_all() resp = dlg.run() value1=spin1.get_value() value2=spin2.get_value() dlg.hide() if resp == gtk.RESPONSE_CANCEL: return () return (value1,value2) def inputbox(title='Input Box', label='Please input the value', parent=None, text=''): """dialog with a input entry return text , or None """ #@TODO: 要直接回车确定 dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) lbl = gtk.Label(label) lbl.set_alignment(0, 0.5) lbl.show() dlg.vbox.pack_start(lbl) entry = gtk.Entry() if text: entry.set_text(text) entry.show() dlg.vbox.pack_start(entry, False) dlg.set_default_response(gtk.RESPONSE_OK) resp = dlg.run() text = entry.get_text() dlg.hide() if resp == gtk.RESPONSE_CANCEL: return None return text def inputbox2(title='2 Input Box', label1='value1:', label2='value2:', parent=None, text1='', text2=''): """dialog with 2 input buttons return (text1,text2) , or () """ strlabel2 = label2 dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) lbl = gtk.Label(title) lbl.set_alignment(0, 0.5) dlg.vbox.pack_start(lbl, False) table1 = gtk.Table() table1.show() table1.set_row_spacings(0) table1.set_col_spacings(0) label2 = gtk.Label(label1) label2.set_alignment(0.5, 0.5) label2.set_padding(0, 0) label2.set_line_wrap(False) label2.show() table1.attach(label2, 0, 1, 0, 1, gtk.FILL, 0, 0, 0) entry2 = gtk.Entry() entry2.set_text("") entry2.set_editable(True) entry2.show() entry2.set_visibility(True) table1.attach(entry2, 1, 2, 0, 1, gtk.EXPAND|gtk.FILL, 0, 0, 0) label3 = gtk.Label(strlabel2) label3.set_alignment(0, 0.5) label3.set_padding(0, 0) label3.set_line_wrap(False) label3.show() table1.attach(label3, 0, 1, 1, 2, gtk.FILL, 0, 0, 0) entry3 = gtk.Entry() entry3.set_text("") entry3.set_editable(True) entry3.show() entry3.set_visibility(True) table1.attach(entry3, 1, 2, 1, 2, gtk.EXPAND|gtk.FILL, 0, 0, 0) if text1: entry2.set_text(text1) if text2: entry3.set_text(text2) dlg.vbox.pack_start(table1) dlg.set_default_response(gtk.RESPONSE_OK) dlg.show_all() resp = dlg.run() text1 = entry2.get_text() text2 = entry3.get_text() dlg.hide() if resp == gtk.RESPONSE_CANCEL: return () return (text1,text2) def savechanges(text=_("Save Changes?"), parent=None): '''Save Changes? return 1, -1, 0 => yes, no, cancel ''' d = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_INFO,) d.add_buttons(gtk.STOCK_YES, 1, gtk.STOCK_NO, -1, gtk.STOCK_CANCEL, 0) d.set_markup(text) d.show_all() response = d.run() d.destroy() return response def infotablebox(title=_("Info"), short=_("Info"), info=[[_("Key:"), _("Value")]], parent=None): '''show info table box ''' dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) label = gtk.Label() label.set_markup(short) label.set_padding(20, 10) label.set_alignment(0, 0) label.show() dlg.vbox.pack_start(label, False, False, 0) ## table = gtk.Table() table.show() # table y = 0 for line in info: x = 0 left = 0 for text in line: label = gtk.Label() #label.set_selectable(1) # 会干扰编辑区选中状态 label.set_padding(10, 3) label.set_alignment(left, 0) label.set_markup("%s" % text) label.show() table.attach(label, x, x+1, y, y+1,) x += 1 left = 1 pass y += 1 pass dlg.vbox.pack_start(table, False, False, 5) response = dlg.run() dlg.destroy() return response def messagedialog(dialog_type, short, long=None, parent=None, buttons=gtk.BUTTONS_OK, additional_buttons=None): d = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_MODAL, type=dialog_type, buttons=buttons) if additional_buttons: d.add_buttons(*additional_buttons) d.set_markup(short) if long: if isinstance(long, gtk.Widget): widget = long elif isinstance(long, basestring): widget = gtk.Label() widget.set_markup(long) else: raise TypeError("long must be a gtk.Widget or a string") expander = gtk.Expander(_("Click here for details")) expander.set_border_width(6) expander.add(widget) d.vbox.pack_end(expander) d.show_all() response = d.run() d.destroy() return response def error(short, long=None, parent=None): """Displays an error message.""" return messagedialog(gtk.MESSAGE_ERROR, short, long, parent) def info(short, long=None, parent=None): """Displays an info message.""" return messagedialog(gtk.MESSAGE_INFO, short, long, parent) def warning(short, long=None, parent=None): """Displays a warning message.""" return messagedialog(gtk.MESSAGE_WARNING, short, long, parent) def yesno(text="OK ?", parent=None): """ return 1 or 0 . ( yes/no ) """ ## return messagedialog(gtk.MESSAGE_WARNING, text, None, parent, ## buttons=gtk.BUTTONS_YES_NO) i = messagedialog(gtk.MESSAGE_INFO, text, None, parent, buttons=gtk.BUTTONS_YES_NO) if i == -8: return 1 return 0 def open(title='', parent=None, patterns=[], mimes=[], name_mimes=[], name_patterns=[], folder=None): """Displays an open dialog. return the full path , or None""" filechooser = gtk.FileChooserDialog(title or _('Open'), parent, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) if patterns: file_filter = gtk.FileFilter() for pattern in patterns: file_filter.add_pattern(pattern) filechooser.set_filter(file_filter) pass if mimes: file_filter = gtk.FileFilter() for mime in mimes: file_filter.add_mime_type(mime) filechooser.add_filter(file_filter) pass if name_mimes: for name, mime in name_mimes: file_filter = gtk.FileFilter() file_filter.set_name(name) file_filter.add_mime_type(mime) filechooser.add_filter(file_filter) if not "*" in [ i[1] for i in name_patterns]: name_patterns += [[_("All Files"), "*"]] pass for name, pattern in name_patterns: file_filter = gtk.FileFilter() file_filter.set_name(name) file_filter.add_pattern(pattern) filechooser.add_filter(file_filter) filechooser.set_default_response(gtk.RESPONSE_OK) if folder: filechooser.set_current_folder(folder) response = filechooser.run() if response != gtk.RESPONSE_OK: filechooser.destroy() return path = filechooser.get_filename() if path and os.access(path, os.R_OK): filechooser.destroy() return path abspath = os.path.abspath(path) error(_('Could not open file "%s"') % abspath, _('The file "%s" could not be opened. ' 'Permission denied.') % abspath) filechooser.destroy() return path def save(title='', parent=None, current_name='', patterns=[], mimes=[], name_mimes=[], name_patterns=[], folder=None): """Displays a save dialog. return the full path , or None """ filechooser = gtk.FileChooserDialog(title or _('Save'), parent, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) if patterns: file_filter = gtk.FileFilter() for pattern in patterns: file_filter.add_pattern(pattern) filechooser.set_filter(file_filter) pass if mimes: file_filter = gtk.FileFilter() for mime in mimes: file_filter.add_mime_type(mime) filechooser.add_filter(file_filter) pass if name_mimes: for name, mime in name_mimes: file_filter = gtk.FileFilter() file_filter.set_name(name) file_filter.add_mime_type(mime) filechooser.add_filter(file_filter) if not "*" in [ i[1] for i in name_patterns]: name_patterns += [[_("All Files"), "*"]] pass for name, pattern in name_patterns: file_filter = gtk.FileFilter() file_filter.set_name(name) file_filter.add_pattern(pattern) filechooser.add_filter(file_filter) if current_name: filechooser.set_current_name(current_name) filechooser.set_default_response(gtk.RESPONSE_OK) if folder: filechooser.set_current_folder(folder) path = None while True: response = filechooser.run() if response != gtk.RESPONSE_OK: path = None break path = filechooser.get_filename() if not os.path.exists(path): break submsg1 = _('A file named "%s" already exists') % os.path.abspath(path) submsg2 = _('Do you which to replace it with the current project?') text = '%s\n\n%s\n' % \ (submsg1, submsg2) result = messagedialog(gtk.MESSAGE_ERROR, text, parent=parent, buttons=gtk.BUTTONS_NONE, additional_buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, _("Replace"), gtk.RESPONSE_YES)) # the user want to overwrite the file if result == gtk.RESPONSE_YES: break filechooser.destroy() return path def test(): #globals()['_'] = lambda s: s #-print combobox(title='ComboBox', label='Combo', texts=['11','22','33']) #-print spinbox2(title='Select the values',label1='cows:',value1=4, label2='rows:',value2=4) #-print textbox(title='Edit The Text',label='Text',text='test text in textbox') #-print inputbox(title='Input a Value',label='Input a value') #-print inputbox2(title='Name and Host',label1='name:',text1='vgh', label2='host:',text2='/') #print open(title='Open a file', patterns=['*.py']) #-print open(title='Open a file', name_mimes={"Python Script":"text/x-python"}) #print save(title='Save a file', current_name='foobar.py') #-print save(title='Save a file', current_name='foobar.py', name_mimes={"Python Script":"text/x-python"}) #-print info(short='This is a InfoBox', long='the long message') #-print yesno(text='Are you OK?') #-print savechanges() error('An error occurred', gtk.Button('Woho')) error('An error occurred', 'Long description bla bla bla bla bla bla bla bla bla\n' 'bla bla bla bla bla lblabl lablab bla bla bla bla bla\n' 'lbalbalbl alabl l blablalb lalba bla bla bla bla lbal\n') if __name__ == '__main__': test() gwrite-0.5.1/gwrite/gtklatex.py0000644000175000017500000002720111534726454015211 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- '''Gtk LaTex @author: U{Jiahua Huang } @license: LGPLv3+ ''' import gtk, gobject import thread import time import subprocess import os, sys import base64 try: import gtksourceview2 except: gtksourceview2 = None try: import i18n except: from gettext import gettext as _ latex_mark_list = [ # ["+", r" + "], # ["-", r" - "], ["", r" \cdot "], ["x", r" \times "], ["/", r" / "], ["÷", r" \frac { } { }"], ["an", r"^{%s}"], ["an", r"_{%s}"], [" ≠ ", r" \neq "], [" ≤ ", r" \le "], [" ≥ ", r" \ge "], [" ≡ ", r" \equiv "], [" ≪ ", r" \ll "], [" ≫ ", r" \gg "], [" ≃ ", r" \simeq "], [" ≈ ", r" \approx "], ["√¯", r" \sqrt[] {%s}"], ["∫", r" \int^{}_{} "], ["∬", r" \iint^{}_{} "], ["∮", r" \oint^{}_{} "], ["[ ]", r"\[ %s \]"], ["( )", r"\( %s \)"], ["{ }", r"\{ %s \}"], ["[≡]", r""" \[ \begin{matrix} a & b & c\\ c & e & f \end{matrix} \] """], ["(≡)", r""" \begin{pmatrix} a & b & c\\ c & e & f \end{pmatrix} """], ["( : )", r"{ } \choose { } "], ["( x )", r"\left( { %s } \right)"], [" ± ", r" \pm "], [" ∓ ", r" \mp "], [" ∨ ", r" \lor" ], [" ∧ ", r" \land "], ["mod", r" \bmod "], [" ∼ ", r" \sim "], ["∥ ", r" \parallel "], [" ⊥ ", r" \perp "], ["", r" \infty "], ["∠", r" \angle "], ["", r" \triangle "], ["∑", r" \sum_{ }^{ } "], ["lim", r"\lim_{ }"], ["⇒", r" \Rightarrow "], ["⇔", r" \Leftrightarrow "], ["∧", r" \wedge "], ["∨", r" \vee "], ["¬", r" \neg "], ["∀", r" \forall "], ["∃", r" \exists "], ["∅", r" \varnothing "], ["∈", r" \in "], ["∉", r" \notin "], ["⊆", r" \subseteq "], ["⊂", r" \subset "], ["∪", r" \cup "], ["⋂", r" \cap "], ["→", r" \to "], ["↦", r" \mapsto "], ["∏", r" \prod "], ["○", r" \circ "], ["sin", r" \sin "], ["cos", r" \cos "], ["tan", r" \tan "], ["ctan", r" \ctab "], ["asin", r" \asin "], ["acos", r" \acos "], ["atan", r" \atan "], ["actan", r" \actan "], ["log", r" \log "], ["ln", r" \ln "], ["...", r" \cdots "], [" ... ", r" \ldots "], ["", r" \vdots "], ["...", r" \ddots "], ["α", r" \alpha "], ["β", r" \beta "], ["Γ", r" \Gamma "], ["γ", r" \gamma "], ["Δ", r" \Delta "], ["δ", r" \delta "], ["ϵ", r" \epsilon "], ["ε", r" \varepsilon "], ["ζ", r" \zeta "], ["η", r" \eta "], ["Θ", r" \Theta "], ["θ", r" \theta "], ["ϑ", r" \vartheta "], ["ι", r" \iota "], ["κ", r" \kappa "], ["Λ", r" \Lambda "], ["λ", r" \lambda "], ["μ", r" \mu "], ["ν", r" \nu "], ["Ξ", r" \Xi "], ["ξ", r" \xi "], ["Π", r" \Pi "], ["π", r" \pi "], ["ϖ", r" \varpi "], ["ρ", r" \rho "], ["ϱ", r" \varrho "], ["Σ", r" \Sigma "], ["σ", r" \sigma "], ["ς", r" \varsigma "], ["τ", r" \tau "], ["Υ", r" \Upsilon "], ["υ", r" \upsilon "], ["Φ", r" \Phi "], ["ϕ", r" \phi "], ["φ", r" \varphi "], ["χ", r" \chi "], ["Ψ", r" \Psi "], ["ψ", r" \psi "], ["Ω", r" \Omega "], ["ω", r" \omega "], ] class GtkToolBoxView(gtk.TextView): '''流式布局 ToolBox ''' def __init__(self, latex=""): '''初始化 ''' self.__gobject_init__() self.unset_flags(gtk.CAN_FOCUS) self.set_editable(0) self.set_wrap_mode(gtk.WRAP_WORD) self.connect('realize', self.on_realize) pass def on_realize(self, *args): ## 将默认 I 形鼠标指针换成箭头 self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW)) pass def add(self, widget): '''插入 Widget ''' buffer = self.get_buffer() iter = buffer.get_end_iter() anchor = buffer.create_child_anchor(iter) buffer.insert(iter, "") widget.set_data('buffer_anchor', anchor) self.add_child_at_anchor(widget, anchor) pass def remove(self, widget): '''删除 widget ''' anchor = widget.get_data('buffer_anchor') if anchor: buffer = self.get_buffer() start = buffer.get_iter_at_child_anchor(anchor) end = buffer.get_iter_at_offset( start.get_offset() + 1 ) buffer.delete(start, end) pass pass class LatexMathExpressionsEditor(gtk.Table): '''LaTex 数学公式编辑器 ''' def __init__(self, latex=""): '''初始化 ''' self.__gobject_init__() self.set_row_spacings(10) self.set_col_spacings(10) ## latex edit scrolledwindow1 = gtk.ScrolledWindow() scrolledwindow1.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrolledwindow1.show() scrolledwindow1.set_shadow_type(gtk.SHADOW_IN) if gtksourceview2: self.latex_textview = gtksourceview2.View() lm = gtksourceview2.language_manager_get_default() language = lm.get_language('latex') buffer = gtksourceview2.Buffer() buffer.set_highlight_syntax(1) buffer.set_language(language) self.latex_textview.set_buffer(buffer) pass else: self.latex_textview = gtk.TextView() pass self.latex_textview.set_wrap_mode(gtk.WRAP_WORD) self.latex_textview.set_cursor_visible(True) self.latex_textview.set_indent(5) self.latex_textview.set_editable(True) self.latex_textview.show() #self.latex_textview.set_size_request(302, 200) buffer = self.latex_textview.get_buffer() buffer.set_text(latex) scrolledwindow1.add(self.latex_textview) self.attach(scrolledwindow1, 0, 1, 0, 1) ## latex preview self.latex_image = gtk.Image() #self.latex_image.set_size_request(200, 100) self.latex_image.set_padding(0, 0) self.latex_image.show() box = gtk.EventBox() box.show() box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#FFFFFF")) box.add(self.latex_image) self.attach(box, 0, 1, 1, 2) ## toolbox toolview = GtkToolBoxView() toolview.show() #toolview.set_size_request(302, 200) for text, mark in latex_mark_list: label = gtk.Label() label.set_markup(text) label.set_size_request(30, 20) label.show() button = gtk.Button() button.unset_flags(gtk.CAN_FOCUS) button.add(label) button.set_relief(gtk.RELIEF_NONE) button.connect("clicked", self.on_insert_tex_mark, text, mark) button.set_tooltip_text(mark) button.show() toolview.add(button) pass scrolledwindow2 = gtk.ScrolledWindow() #scrolledwindow2.set_size_request(300, 400) scrolledwindow2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrolledwindow2.show() scrolledwindow2.set_shadow_type(gtk.SHADOW_IN) scrolledwindow2.add(toolview) self.attach(scrolledwindow2, 1, 2, 0, 2) self.show_all() thread.start_new_thread(self._up_preview, ()) pass def get_latex(self, *args): '''获取 LaTex ''' buffer = self.latex_textview.get_buffer() return buffer.get_text(buffer.get_start_iter(),buffer.get_end_iter()) def set_pic(self, data): '''设置图像 ''' if not data: return self.latex_image.set_from_stock(gtk.STOCK_DIALOG_ERROR, 2) pix = gtk.gdk.PixbufLoader() pix.write(data) pix.close() self.latex_image.set_from_pixbuf(pix.get_pixbuf()) return def _up_preview(self, *args): '''用于定时更新预览 ''' old_latex = "" while True: time.sleep(1) if not self.get_window(): break latex = self.get_latex() if latex == old_latex: continue pic = tex2gif(latex, 1) old_latex = self.get_latex() if latex == self.get_latex(): gobject.idle_add(self.set_pic, pic) pass pass #-print 'done' return def up_preview(self, pic): '''更新预览''' return def insert_latex_mark(self, view, mark, text=""): '''在 gtk.TextView 插入 LaTex 标记 ''' buffer = view.get_buffer() bounds = buffer.get_selection_bounds() select = bounds and buffer.get_slice(bounds[0], bounds[1]) or text if mark.count("%") == 1: mark = mark % select pass else: mark = mark + select pass buffer.delete_selection(1, 1) buffer.insert_at_cursor(mark) pass def on_insert_tex_mark(self, widget, text, mark): print 'on_insert_tex_mark:', text, mark self.insert_latex_mark(self.latex_textview, mark) pass def latex_dlg(latex="", title=_("LaTeX math expressions"), parent=None): dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) dlg.set_default_size(680, 400) editor = LatexMathExpressionsEditor(latex) dlg.vbox.pack_start(editor, True, True, 5) dlg.show_all() resp = dlg.run() latex = editor.get_latex() dlg.destroy() if resp == gtk.RESPONSE_OK: return latex return None def stastr(stri): '''处理字符串的 ' " ''' return stri.replace("\\","\\\\").replace(r'"',r'\"').replace(r"'",r"\'").replace('\n',r'\n') def tex2gif(tex, transparent=1): '''将 latex 数学公式转为 gif 图片,依赖 mimetex mimetex -d -s 7 '公式' ''' if transparent: cmd = ['mimetex', '-d', '-s', '4', tex] pass else: cmd = ['mimetex', '-d', '-o', '-s', '4', tex] pass i = subprocess.Popen(cmd, stdout=subprocess.PIPE) gif = i.communicate()[0] if gif.startswith('GIF'): return gif return "" def gif2base64(gif): '''将 gif 图像转为 base64 内联图像 ''' return 'data:image/gif;base64,%s' % base64.encodestring(gif).replace('\n', '') def tex2base64(tex): '''将 latex 数学公式转为 base64 内联图像 ''' return gif2base64(tex2gif(tex)) def tex2html(tex): '''将 latex 数学公式转为 base64 内联图像 ''' return 'mimetex:%s' % (stastr(tex), gif2base64(tex2gif(tex))) if __name__=="__main__": gtk.gdk.threads_init() latex = ' '.join(sys.argv[1:]) or 'E=MC^2' latex = latex_dlg(latex) print latex #print tex2html(latex) pass gwrite-0.5.1/gwrite/gwrite.py0000755000175000017500000025667411534726454014714 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- '''GWrite @author: U{Jiahua Huang } @license: LGPLv3+ ''' __version__ = '0.5.1' import gtk, gobject import gtkdialogs import gtklatex import config import os, sys import thread import re import urllib2 try: import i18n except: from gettext import gettext as _ def get_doctitle(html): title = '' title = (re.findall(r'''([^\0]*)''', html)+[_("NewDocument")])[0] return title def proc_webkit_color(*webviews): ## 设置样式,让 WebKit 背景色使用 Gtk 颜色 style = webviews[0].get_style() html_bg_color = str(style.base[gtk.STATE_NORMAL]) html_fg_color = str(style.text[gtk.STATE_NORMAL]) user_stylesheet = ''' html { background-color: %s; color: %s;\n}''' % (html_bg_color, html_fg_color) user_stylesheet_file = config.user_stylesheet_file file(user_stylesheet_file, 'w').write(user_stylesheet) user_stylesheet_uri = 'file://' + user_stylesheet_file for webview in webviews: settings = webview.get_settings() settings.set_property('user-stylesheet-uri', user_stylesheet_uri) pass def menu_find_with_stock(menu, stock): # 查找菜单中对应 stock 的菜单项位置 n = 0 for i in menu.get_children(): try: if i.get_image().get_stock()[0] == stock: return n except: pass n += 1 pass return -1 Windows = [] new_num = 1 Title = _("GWrite") ## 是否单实例模式 #single_instance_mode = 0 #mdi_mode = 1 class MainWindow: def __init__(self, editfile='', create = True, accel_group = None): self.editfile = editfile ## 考虑已经打开文档的情况 if editfile: for i in Windows: if i.editfile == editfile: #-print _('File "%s" already opened') % editfile i.window.show() i.window.present() #@TODO: 让 edit 获得焦点 i.window.grab_focus() i.edit.grab_focus() del self return pass pass ## Windows.append(self) import webkitedit # 推迟 import webkitedit ## if accel_group is None: self.accel_group = gtk.AccelGroup() else: self.accel_group = accel_group if create: self.window = gtk.Window() gtk.window_set_default_icon_name("gtk-dnd") self.window.set_icon_name("gtk-dnd") self.window.set_default_size(780, 550) self.window.set_title(Title) if editfile: self.window.set_title(os.path.basename(self.editfile) + ' - ' + Title) self.window.add_accel_group(self.accel_group) self.window.show() self.window.connect("delete_event", self.on_close) ## 用 Alt-1, Alt-2... 来切换标签页,gtk.gdk.MOD1_MASK 是 Alt for k in range(1, 10): self.accel_group.connect_group(gtk.gdk.keyval_from_name(str(k)), gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE, self.on_accel_connect_group) pass self.vbox1 = gtk.VBox(False, 0) self.vbox1.show() menubar1 = gtk.MenuBar() menubar1.show() menuitem_file = gtk.MenuItem(_("_File")) menuitem_file.show() menu_file = gtk.Menu() menu_file.append(gtk.TearoffMenuItem()) self.menu_file = menu_file menuitem_new = gtk.ImageMenuItem("gtk-new") menuitem_new.show() menuitem_new.connect("activate", self.on_new) menuitem_new.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("n"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_new) if config.mdi_mode: menuitem_new_window = gtk.ImageMenuItem(_("New _Window")) menuitem_new_window.show() img = gtk.image_new_from_stock(gtk.STOCK_NEW, gtk.ICON_SIZE_MENU) menuitem_new_window.set_image(img) menuitem_new_window.connect("activate", self.on_new_window) menuitem_new_window.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("n"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_new_window) pass menuitem_open = gtk.ImageMenuItem("gtk-open") menuitem_open.show() menuitem_open.connect("activate", self.on_open) menuitem_open.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("o"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_open) menuitem_save = gtk.ImageMenuItem("gtk-save") menuitem_save.show() menuitem_save.connect("activate", self.on_save) menuitem_save.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("s"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_save) menuitem_save_as = gtk.ImageMenuItem("gtk-save-as") menuitem_save_as.show() menuitem_save_as.connect("activate", self.on_save_as) menu_file.append(menuitem_save_as) menu_file.append(gtk.MenuItem()) menuitem = gtk.ImageMenuItem("gtk-properties") menuitem.show() menuitem.connect("activate", self.on_word_counts) menu_file.append(menuitem) menuitem_print = gtk.ImageMenuItem("gtk-print") menuitem_print.show() menuitem_print.connect("activate", self.on_print) menuitem_print.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("p"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_print) menu_file.append(gtk.MenuItem()) ## 最近使用文件菜单 ################ self.recent = gtk.RecentManager() menu_recent = gtk.RecentChooserMenu(self.recent) menu_recent.set_limit(25) #if editfile: self.add_recent(editfile) #改在 new_edit() 里统一添加 ## self.file_filter = gtk.RecentFilter() self.file_filter.add_mime_type("text/html") menu_recent.set_filter(self.file_filter) menu_recent.connect("item-activated", self.on_select_recent) menuitem_recent = gtk.ImageMenuItem(_("_Recently")) menuitem_recent.set_image(gtk.image_new_from_icon_name("document-open-recent", gtk.ICON_SIZE_MENU)) menuitem_recent.set_submenu(menu_recent) menu_file.append(menuitem_recent) ##################################### menuitem_separatormenuitem1 = gtk.MenuItem() menuitem_separatormenuitem1.show() menu_file.append(menuitem_separatormenuitem1) menuitem_close = gtk.ImageMenuItem("gtk-close") menuitem_close.show() menuitem_close.connect("activate", self.close_tab) menuitem_close.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("w"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_close) if config.mdi_mode: menuitem_close_window = gtk.ImageMenuItem(_("Close Win_dow")) menuitem_close_window.show() img = gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) menuitem_close_window.set_image(img) menuitem_close_window.connect("activate", self.on_close) menuitem_close_window.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("w"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_close_window) pass menuitem_quit = gtk.ImageMenuItem("gtk-quit") menuitem_quit.show() menuitem_quit.connect("activate", self.on_quit) menuitem_quit.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("q"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_file.append(menuitem_quit) menuitem_file.set_submenu(menu_file) menubar1.append(menuitem_file) menuitem_edit = gtk.MenuItem(_("_Edit")) menuitem_edit.show() menu_edit = gtk.Menu() menu_edit.append(gtk.TearoffMenuItem()) menuitem_undo = gtk.ImageMenuItem("gtk-undo") menuitem_undo.show() menuitem_undo.connect("activate", self.do_undo) menu_edit.append(menuitem_undo) menuitem_redo = gtk.ImageMenuItem("gtk-redo") menuitem_redo.show() menuitem_redo.connect("activate", self.do_redo) menu_edit.append(menuitem_redo) menuitem_separator2 = gtk.MenuItem() menuitem_separator2.show() menu_edit.append(menuitem_separator2) menuitem_cut = gtk.ImageMenuItem("gtk-cut") menuitem_cut.show() menuitem_cut.connect("activate", self.do_cut) menu_edit.append(menuitem_cut) menuitem_copy = gtk.ImageMenuItem("gtk-copy") menuitem_copy.show() menuitem_copy.connect("activate", self.do_copy) menu_edit.append(menuitem_copy) menuitem_paste = gtk.ImageMenuItem("gtk-paste") menuitem_paste.show() menuitem_paste.connect("activate", self.do_paste) menu_edit.append(menuitem_paste) menuitem_paste_unformatted = gtk.ImageMenuItem(_("Pa_ste Unformatted")) menuitem_paste_unformatted.show() menuitem_paste_unformatted.connect("activate", self.do_paste_unformatted) menuitem_paste_unformatted.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("v"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_edit.append(menuitem_paste_unformatted) menuitem_delete = gtk.ImageMenuItem("gtk-delete") menuitem_delete.show() menuitem_delete.connect("activate", self.do_delete) menu_edit.append(menuitem_delete) menuitem_separator3 = gtk.MenuItem() menuitem_separator3.show() menu_edit.append(menuitem_separator3) menuitem_select_all = gtk.ImageMenuItem("gtk-select-all") menuitem_select_all.show() menuitem_select_all.connect("activate", self.do_selectall) menu_edit.append(menuitem_select_all) menuitem_separator12 = gtk.MenuItem() menuitem_separator12.show() menu_edit.append(menuitem_separator12) menuitem_find = gtk.ImageMenuItem("gtk-find") menuitem_find.show() menuitem_find.connect("activate", self.show_findbar) menuitem_find.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("f"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_edit.append(menuitem_find) menuitem_find_and_replace = gtk.ImageMenuItem("gtk-find-and-replace") menuitem_find_and_replace.show() menuitem_find_and_replace.connect("activate", self.show_findbar) menu_edit.append(menuitem_find_and_replace) ## menu_edit.append(gtk.MenuItem()) menuitem = gtk.ImageMenuItem("gtk-preferences") menuitem.show() menuitem.connect("activate", lambda *i: (config.show_preference_dlg(), config.write())) menu_edit.append(menuitem) ## menuitem_edit.set_submenu(menu_edit) menubar1.append(menuitem_edit) menuitem_view = gtk.MenuItem(_("_View")) menuitem_view.show() menu_view = gtk.Menu() menu_view.append(gtk.TearoffMenuItem()) ## 缩放菜单 menuitem_zoom_in = gtk.ImageMenuItem(gtk.STOCK_ZOOM_IN) menuitem_zoom_in.connect("activate", self.zoom_in) # Ctrl++ menuitem_zoom_in.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("equal"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menuitem_zoom_in.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("plus"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menuitem_zoom_in.show() menu_view.append(menuitem_zoom_in) menuitem_zoom_out = gtk.ImageMenuItem(gtk.STOCK_ZOOM_OUT) menuitem_zoom_out.connect("activate", self.zoom_out) # Ctrl+- menuitem_zoom_out.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("minus"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menuitem_zoom_out.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("underscore"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menuitem_zoom_out.show() menu_view.append(menuitem_zoom_out) menuitem_zoom_100 = gtk.ImageMenuItem(gtk.STOCK_ZOOM_100) menuitem_zoom_100.connect("activate", self.zoom_100) # Ctrl+0 menuitem_zoom_100.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("0"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menuitem_zoom_100.show() menu_view.append(menuitem_zoom_100) ## menuitem_separator10 = gtk.MenuItem() menuitem_separator10.show() menu_view.append(menuitem_separator10) menuitem_update_contents = gtk.ImageMenuItem(_("Update _Contents")) menuitem_update_contents.show() menuitem_update_contents.connect("activate", self.view_update_contents) img = gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU) menuitem_update_contents.set_image(img) menu_view.append(menuitem_update_contents) menuitem_toggle_numbered_title = gtk.ImageMenuItem(_("Toggle _Numbered Title")) menuitem_toggle_numbered_title.show() menuitem_toggle_numbered_title.connect("activate", self.view_toggle_autonumber) img = gtk.image_new_from_stock(gtk.STOCK_SORT_DESCENDING, gtk.ICON_SIZE_MENU) menuitem_toggle_numbered_title.set_image(img) menu_view.append(menuitem_toggle_numbered_title) menuitem_update_images = gtk.ImageMenuItem(_("Update _Images")) menuitem_update_images.show() menuitem_update_images.connect("activate", self.do_update_images) img = gtk.image_new_from_icon_name('stock_insert_image', gtk.ICON_SIZE_MENU) menuitem_update_images.set_image(img) menu_view.append(menuitem_update_images) menuitem_separator10 = gtk.MenuItem() menuitem_separator10.show() menu_view.append(menuitem_separator10) menuitem_view_source = gtk.ImageMenuItem(_("So_urce/Visual")) menuitem_view_source.show() menuitem_view_source.connect("activate", self.view_sourceview) menuitem_view_source.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("u"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_view-html-source', gtk.ICON_SIZE_MENU) menuitem_view_source.set_image(img) menu_view.append(menuitem_view_source) menuitem_view.set_submenu(menu_view) menubar1.append(menuitem_view) menuitem_insert = gtk.MenuItem(_("_Insert")) menuitem_insert.show() menu_insert = gtk.Menu() menu_insert.append(gtk.TearoffMenuItem()) menuitem_picture = gtk.ImageMenuItem(_("_Picture")) menuitem_picture.show() menuitem_picture.connect("activate", self.do_insertimage) img = gtk.image_new_from_icon_name('stock_insert_image', gtk.ICON_SIZE_MENU) menuitem_picture.set_image(img) menu_insert.append(menuitem_picture) menuitem_link = gtk.ImageMenuItem(_("_Link")) menuitem_link.show() menuitem_link.connect("activate", self.do_createlink) menuitem_link.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("k"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_link', gtk.ICON_SIZE_MENU) menuitem_link.set_image(img) menu_insert.append(menuitem_link) menuitem_horizontalrule = gtk.ImageMenuItem(_("Horizontal_Rule")) menuitem_horizontalrule.show() menuitem_horizontalrule.connect("activate", self.do_inserthorizontalrule) img = gtk.image_new_from_icon_name('stock_insert-rule', gtk.ICON_SIZE_MENU) menuitem_horizontalrule.set_image(img) menu_insert.append(menuitem_horizontalrule) menuitem_insert_table = gtk.ImageMenuItem(_("_Table")) menuitem_insert_table.show() menuitem_insert_table.connect("activate", self.do_insert_table) img = gtk.image_new_from_icon_name('stock_insert-table', gtk.ICON_SIZE_MENU) menuitem_insert_table.set_image(img) menu_insert.append(menuitem_insert_table) menuitem_insert_html = gtk.ImageMenuItem(_("_HTML")) menuitem_insert_html.show() menuitem_insert_html.connect("activate", self.do_insert_html) img = gtk.image_new_from_icon_name('stock_view-html-source', gtk.ICON_SIZE_MENU) menuitem_insert_html.set_image(img) menu_insert.append(menuitem_insert_html) menuitem_separator9 = gtk.MenuItem() menuitem_separator9.show() menu_insert.append(menuitem_separator9) ## menuitem_latex_math_equation = gtk.ImageMenuItem(_("LaTeX _Equation")) menuitem_latex_math_equation.show() menuitem_latex_math_equation.connect("activate", self.do_insert_latex_math_equation) menu_insert.append(menuitem_latex_math_equation) menu_insert.append(gtk.MenuItem()) ## menuitem_insert_contents = gtk.ImageMenuItem(_("_Contents")) menuitem_insert_contents.show() menuitem_insert_contents.connect("activate", self.do_insert_contents) img = gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU) menuitem_insert_contents.set_image(img) menu_insert.append(menuitem_insert_contents) menuitem_insert.set_submenu(menu_insert) menubar1.append(menuitem_insert) menuitem_style = gtk.MenuItem(_("_Style")) menuitem_style.show() menu_style = gtk.Menu() menu_style.append(gtk.TearoffMenuItem()) menuitem_normal = gtk.ImageMenuItem(_("_Normal")) menuitem_normal.show() menuitem_normal.connect("activate", self.do_formatblock_p) menuitem_normal.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("0"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_insert_section', gtk.ICON_SIZE_MENU) menuitem_normal.set_image(img) menu_style.append(menuitem_normal) menuitem_separator4 = gtk.MenuItem() menuitem_separator4.show() menu_style.append(menuitem_separator4) menuitem_heading_1 = gtk.ImageMenuItem(_("Heading _1")) menuitem_heading_1.show() menuitem_heading_1.connect("activate", self.do_formatblock_h1) menuitem_heading_1.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("1"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_insert-header', gtk.ICON_SIZE_MENU) menuitem_heading_1.set_image(img) menu_style.append(menuitem_heading_1) menuitem_heading_2 = gtk.ImageMenuItem(_("Heading _2")) menuitem_heading_2.show() menuitem_heading_2.connect("activate", self.do_formatblock_h2) menuitem_heading_2.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("2"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_line-spacing-2', gtk.ICON_SIZE_MENU) menuitem_heading_2.set_image(img) menu_style.append(menuitem_heading_2) menuitem_heading_3 = gtk.ImageMenuItem(_("Heading _3")) menuitem_heading_3.show() menuitem_heading_3.connect("activate", self.do_formatblock_h3) menuitem_heading_3.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("3"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_line-spacing-1', gtk.ICON_SIZE_MENU) menuitem_heading_3.set_image(img) menu_style.append(menuitem_heading_3) menuitem_heading_4 = gtk.ImageMenuItem(_("Heading _4")) menuitem_heading_4.show() menuitem_heading_4.connect("activate", self.do_formatblock_h4) menuitem_heading_4.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("4"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_line-spacing-1.5', gtk.ICON_SIZE_MENU) menuitem_heading_4.set_image(img) menu_style.append(menuitem_heading_4) menuitem_heading_5 = gtk.ImageMenuItem(_("Heading _5")) menuitem_heading_5.show() menuitem_heading_5.connect("activate", self.do_formatblock_h5) menuitem_heading_5.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("5"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_list_enum-off', gtk.ICON_SIZE_MENU) menuitem_heading_5.set_image(img) menu_style.append(menuitem_heading_5) menuitem_heading_6 = gtk.ImageMenuItem(_("Heading _6")) menuitem_heading_6.show() menuitem_heading_6.connect("activate", self.do_formatblock_h6) menuitem_heading_6.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("6"), gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_list_enum-off', gtk.ICON_SIZE_MENU) menuitem_heading_6.set_image(img) menu_style.append(menuitem_heading_6) menuitem_separator5 = gtk.MenuItem() menuitem_separator5.show() menu_style.append(menuitem_separator5) menuitem_bulleted_list = gtk.ImageMenuItem(_("_Bulleted List")) menuitem_bulleted_list.show() menuitem_bulleted_list.connect("activate", self.do_insertunorderedlist) img = gtk.image_new_from_icon_name('stock_list_bullet', gtk.ICON_SIZE_MENU) menuitem_bulleted_list.set_image(img) menu_style.append(menuitem_bulleted_list) menuitem_numbered_list = gtk.ImageMenuItem(_("Numbered _List")) menuitem_numbered_list.show() menuitem_numbered_list.connect("activate", self.do_insertorderedlist) img = gtk.image_new_from_icon_name('stock_list_enum', gtk.ICON_SIZE_MENU) menuitem_numbered_list.set_image(img) menu_style.append(menuitem_numbered_list) menuitem_separator6 = gtk.MenuItem() menuitem_separator6.show() menu_style.append(menuitem_separator6) div1 = gtk.ImageMenuItem(_("Di_v")) div1.show() div1.connect("activate", self.do_formatblock_div) img = gtk.image_new_from_icon_name('stock_tools-hyphenation', gtk.ICON_SIZE_MENU) div1.set_image(img) menu_style.append(div1) address1 = gtk.ImageMenuItem(_("A_ddress")) address1.show() address1.connect("activate", self.do_formatblock_address) img = gtk.image_new_from_icon_name('stock_tools-hyphenation', gtk.ICON_SIZE_MENU) address1.set_image(img) menu_style.append(address1) #menuitem_formatblock_code = gtk.ImageMenuItem(_("_Code")) #menuitem_formatblock_code.show() #menuitem_formatblock_code.connect("activate", self.do_formatblock_code) # #img = gtk.image_new_from_icon_name('stock_text-monospaced', gtk.ICON_SIZE_MENU) #menuitem_formatblock_code.set_image(img) #menu_style.append(menuitem_formatblock_code) menuitem_formatblock_blockquote = gtk.ImageMenuItem(_("Block_quote")) menuitem_formatblock_blockquote.show() menuitem_formatblock_blockquote.connect("activate", self.do_formatblock_blockquote) img = gtk.image_new_from_icon_name('stock_list-insert-unnumbered', gtk.ICON_SIZE_MENU) menuitem_formatblock_blockquote.set_image(img) menu_style.append(menuitem_formatblock_blockquote) menuitem_formatblock_pre = gtk.ImageMenuItem(_("_Preformat")) menuitem_formatblock_pre.show() menuitem_formatblock_pre.connect("activate", self.do_formatblock_pre) menuitem_formatblock_pre.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("t"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_text-quickedit', gtk.ICON_SIZE_MENU) menuitem_formatblock_pre.set_image(img) menu_style.append(menuitem_formatblock_pre) menuitem_style.set_submenu(menu_style) menubar1.append(menuitem_style) menuitem_format = gtk.MenuItem(_("For_mat")) menuitem_format.show() menu_format = gtk.Menu() menu_format.append(gtk.TearoffMenuItem()) menuitem_bold = gtk.ImageMenuItem("gtk-bold") menuitem_bold.show() menuitem_bold.connect("activate", self.on_bold) menuitem_bold.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("b"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_bold) menuitem_italic = gtk.ImageMenuItem("gtk-italic") menuitem_italic.show() menuitem_italic.connect("activate", self.do_italic) menuitem_italic.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("i"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_italic) menuitem_underline = gtk.ImageMenuItem("gtk-underline") menuitem_underline.show() menuitem_underline.connect("activate", self.do_underline) menuitem_underline.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("u"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_underline) menuitem_strikethrough = gtk.ImageMenuItem("gtk-strikethrough") menuitem_strikethrough.show() menuitem_strikethrough.connect("activate", self.do_strikethrough) menu_format.append(menuitem_strikethrough) self.separator7 = gtk.MenuItem() self.separator7.show() menu_format.append(self.separator7) menuitem_font_fontname = gtk.ImageMenuItem("gtk-select-font") menuitem_font_fontname.show() #menuitem_font_fontname.connect("activate", self.do_font_fontname) ## 字体列表菜单 ######################################### self.fontname_menu = gtk.Menu() self.fontname_menu.append(gtk.TearoffMenuItem()) fontnames = sorted(( familie.get_name() for familie in gtk.Label().get_pango_context().list_families() )) ## 调整字体列表顺序,将中文字体提至前列 for fontname in fontnames: try: fontname.decode('ascii') pass except: fontnames.remove(fontname) fontnames.insert(0, fontname) pass pass for fontname in ['Serif', 'Sans', 'Sans-serif', 'Monospace', ''] + fontnames: if fontname: menu = gtk.MenuItem(fontname) menu.connect("activate", self.do_font_fontname, fontname) pass else: menu = gtk.MenuItem() pass menu.show() self.fontname_menu.append(menu) pass self.fontname_menu.show() menuitem_font_fontname.set_submenu(self.fontname_menu) ########################################### menu_format.append(menuitem_font_fontname) menuitem_font_size = gtk.ImageMenuItem(_("Font _Size")) menuitem_font_size.show() img = gtk.image_new_from_icon_name('stock_font-size', gtk.ICON_SIZE_MENU) menuitem_font_size.set_image(img) self.font_size1_menu = gtk.Menu() self.font_size1_menu.append(gtk.TearoffMenuItem()) menuitem_fontsize_1 = gtk.MenuItem(_("_1")) menuitem_fontsize_1.show() menuitem_fontsize_1.connect("activate", self.do_fontsize_1) self.font_size1_menu.append(menuitem_fontsize_1) menuitem_fontsize_2 = gtk.MenuItem(_("_2")) menuitem_fontsize_2.show() menuitem_fontsize_2.connect("activate", self.do_fontsize_2) self.font_size1_menu.append(menuitem_fontsize_2) menuitem_fontsize_3 = gtk.MenuItem(_("_3")) menuitem_fontsize_3.show() menuitem_fontsize_3.connect("activate", self.do_fontsize_3) self.font_size1_menu.append(menuitem_fontsize_3) menuitem_fontsize_4 = gtk.MenuItem(_("_4")) menuitem_fontsize_4.show() menuitem_fontsize_4.connect("activate", self.do_fontsize_4) self.font_size1_menu.append(menuitem_fontsize_4) menuitem_fontsize_5 = gtk.MenuItem(_("_5")) menuitem_fontsize_5.show() menuitem_fontsize_5.connect("activate", self.do_fontsize_5) self.font_size1_menu.append(menuitem_fontsize_5) menuitem_fontsize_6 = gtk.MenuItem(_("_6")) menuitem_fontsize_6.show() menuitem_fontsize_6.connect("activate", self.do_fontsize_6) self.font_size1_menu.append(menuitem_fontsize_6) menuitem_fontsize_7 = gtk.MenuItem(_("_7")) menuitem_fontsize_7.show() menuitem_fontsize_7.connect("activate", self.do_fontsize_7) self.font_size1_menu.append(menuitem_fontsize_7) menuitem_font_size.set_submenu(self.font_size1_menu) menu_format.append(menuitem_font_size) menuitem_color = gtk.ImageMenuItem("gtk-select-color") menuitem_color.show() menuitem_color.connect("activate", self.on_color_select_forecolor) menu_format.append(menuitem_color) menuitem_bg_color = gtk.ImageMenuItem(_("_Highlight")) menuitem_bg_color.show() menuitem_bg_color.connect("activate", self.do_color_hilitecolor) menuitem_bg_color.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("h"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_text_color_hilight', gtk.ICON_SIZE_MENU) menuitem_bg_color.set_image(img) menu_format.append(menuitem_bg_color) menuitem_bg_color_select = gtk.ImageMenuItem(_("_HiliteColor")) menuitem_bg_color_select.show() menuitem_bg_color_select.connect("activate", self.on_color_select_hilitecolor) img = gtk.image_new_from_stock(gtk.STOCK_SELECT_COLOR, gtk.ICON_SIZE_MENU) menuitem_bg_color_select.set_image(img) menu_format.append(menuitem_bg_color_select) menuitem_clearformat = gtk.ImageMenuItem(_("_Clear format")) img = gtk.image_new_from_icon_name("gtk-clear", gtk.ICON_SIZE_MENU) menuitem_clearformat.set_image(img) menuitem_clearformat.show() menuitem_clearformat.connect("activate", self.do_removeformat) menuitem_clearformat.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("backslash"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_clearformat) self.separator8 = gtk.MenuItem() self.separator8.show() menu_format.append(self.separator8) menuitem_justifyleft = gtk.ImageMenuItem("gtk-justify-left") menuitem_justifyleft.show() menuitem_justifyleft.connect("activate", self.do_justifyleft) menuitem_justifyleft.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("l"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_justifyleft) menuitem_justifycenter = gtk.ImageMenuItem("gtk-justify-center") menuitem_justifycenter.show() menuitem_justifycenter.connect("activate", self.do_justifycenter) menuitem_justifycenter.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("e"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_justifycenter) menuitem_justifyright = gtk.ImageMenuItem("gtk-justify-right") menuitem_justifyright.show() menuitem_justifyright.connect("activate", self.do_justifyright) menuitem_justifyright.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("r"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_justifyright) menuitem_justifyfull = gtk.ImageMenuItem("gtk-justify-fill") menuitem_justifyfull.show() menuitem_justifyfull.connect("activate", self.do_justifyfull) menuitem_justifyfull.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("j"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_format.append(menuitem_justifyfull) self.separator11 = gtk.MenuItem() self.separator11.show() menu_format.append(self.separator11) menuitem_increase_indent = gtk.ImageMenuItem("gtk-indent") menuitem_increase_indent.show() menuitem_increase_indent.connect("activate", self.do_indent) menu_format.append(menuitem_increase_indent) menuitem_decrease_indent = gtk.ImageMenuItem("gtk-unindent") menuitem_decrease_indent.show() menuitem_decrease_indent.connect("activate", self.do_outdent) menu_format.append(menuitem_decrease_indent) self.separator16 = gtk.MenuItem() self.separator16.show() menu_format.append(self.separator16) menuitem_superscript = gtk.ImageMenuItem(_("Su_perscript")) menuitem_superscript.show() menuitem_superscript.connect("activate", self.do_superscript) menuitem_superscript.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("period"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_superscript', gtk.ICON_SIZE_MENU) menuitem_superscript.set_image(img) menu_format.append(menuitem_superscript) menuitem_subscript = gtk.ImageMenuItem(_("Subs_cript")) menuitem_subscript.show() menuitem_subscript.connect("activate", self.do_subscript) menuitem_subscript.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("comma"), gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) img = gtk.image_new_from_icon_name('stock_subscript', gtk.ICON_SIZE_MENU) menuitem_subscript.set_image(img) menu_format.append(menuitem_subscript) menuitem_format.set_submenu(menu_format) menubar1.append(menuitem_format) ## menuitem_tools = gtk.MenuItem(_("_Tools")) menuitem_tools.show() menu_tools = gtk.Menu() menu_tools.append(gtk.TearoffMenuItem()) menuitem_word_count = gtk.ImageMenuItem(_("_Word Count")) img = gtk.image_new_from_icon_name('gtk-index', gtk.ICON_SIZE_MENU) menuitem_word_count.set_image(img) menuitem_word_count.show() menuitem_word_count.connect("activate", self.on_word_counts) menuitem_word_count.add_accelerator("activate", self.accel_group, gtk.gdk.keyval_from_name("c"), gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, gtk.ACCEL_VISIBLE) menu_tools.append(menuitem_word_count) menuitem_tools.set_submenu(menu_tools) menubar1.append(menuitem_tools) ## menuitem_help = gtk.MenuItem(_("_Help")) menuitem_help.show() menu_help = gtk.Menu() menu_help.append(gtk.TearoffMenuItem()) menuitem_about = gtk.ImageMenuItem("gtk-about") menuitem_about.show() menuitem_about.connect("activate", self.on_about) menu_help.append(menuitem_about) menuitem_help.set_submenu(menu_help) menubar1.append(menuitem_help) menubar1.show_all() self.vbox1.pack_start(menubar1, False, False, 0) ## 工具栏 self.toolbar1 = gtk.Toolbar() self.toolbar1.show() toolbutton_new = gtk.ToolButton() toolbutton_new.set_tooltip_text(_("New")) toolbutton_new.show() toolbutton_new.set_stock_id(gtk.STOCK_NEW) toolbutton_new.connect("clicked", self.on_new) self.toolbar1.add(toolbutton_new) toolbutton_open = gtk.MenuToolButton(gtk.STOCK_OPEN) toolbutton_open.set_tooltip_text(_("Open")) toolbutton_open.show() #toolbutton_open.set_stock_id(gtk.STOCK_OPEN) toolbutton_open.connect("clicked", self.on_open) toolbutton_open.set_menu(menu_recent) self.toolbar1.add(toolbutton_open) toolbutton_save = gtk.ToolButton() toolbutton_save.set_tooltip_text(_("Save")) toolbutton_save.show() toolbutton_save.set_stock_id(gtk.STOCK_SAVE) toolbutton_save.connect("clicked", self.on_save) self.toolbar1.add(toolbutton_save) separatortoolitem1 = gtk.SeparatorToolItem() separatortoolitem1.show() self.toolbar1.add(separatortoolitem1) toolbutton_undo = gtk.ToolButton() toolbutton_undo.set_tooltip_text(_("Undo")) toolbutton_undo.show() toolbutton_undo.set_stock_id(gtk.STOCK_UNDO) toolbutton_undo.connect("clicked", self.do_undo) self.toolbar1.add(toolbutton_undo) toolbutton_redo = gtk.ToolButton() toolbutton_redo.set_tooltip_text(_("Redo")) toolbutton_redo.show() toolbutton_redo.set_stock_id(gtk.STOCK_REDO) toolbutton_redo.connect("clicked", self.do_redo) self.toolbar1.add(toolbutton_redo) separatortoolitem3 = gtk.SeparatorToolItem() separatortoolitem3.show() self.toolbar1.add(separatortoolitem3) toolbutton_cut = gtk.ToolButton() toolbutton_cut.set_tooltip_text(_("Cut")) toolbutton_cut.show() toolbutton_cut.set_stock_id(gtk.STOCK_CUT) toolbutton_cut.connect("clicked", self.do_cut) self.toolbar1.add(toolbutton_cut) toolbutton_copy = gtk.ToolButton() toolbutton_copy.set_tooltip_text(_("Copy")) toolbutton_copy.show() toolbutton_copy.set_stock_id(gtk.STOCK_COPY) toolbutton_copy.connect("clicked", self.do_copy) self.toolbar1.add(toolbutton_copy) toolbutton_paste = gtk.ToolButton() toolbutton_paste.set_tooltip_text(_("Paste")) toolbutton_paste.show() toolbutton_paste.set_stock_id(gtk.STOCK_PASTE) toolbutton_paste.connect("clicked", self.do_paste) self.toolbar1.add(toolbutton_paste) separatortoolitem2 = gtk.SeparatorToolItem() separatortoolitem2.show() self.toolbar1.add(separatortoolitem2) ## p, h1, h2 样式 label1 = gtk.Label("") label1.set_markup("P") button1 = gtk.ToolButton(label1, _("Paragraph")) button1.set_tooltip_text(_("Paragraph")) button1.connect("clicked", self.do_formatblock_p) button1.show() self.toolbar1.add( button1) label1 = gtk.Label("") label1.set_markup("H1") button1 = gtk.ToolButton(label1, _("Heading 1")) button1.set_tooltip_text(_("Heading 1")) button1.connect("clicked", self.do_formatblock_h1) button1.show() self.toolbar1.add( button1) label1 = gtk.Label("") label1.set_markup("H2") button1 = gtk.ToolButton(label1, _("Heading 2")) button1.set_tooltip_text(_("Heading 2")) button1.connect("clicked", self.do_formatblock_h2) button1.show() self.toolbar1.add( button1) ## h3 样式 label1 = gtk.Label("") label1.set_markup("H3") button1 = gtk.MenuToolButton(label1, _("Heading 3")) button1.set_tooltip_text(_("Heading 3")) button1.set_arrow_tooltip_markup(_("Style")) button1.connect("clicked", self.do_formatblock_h3) button1.show() self.toolbar1.add( button1) menu_style = gtk.Menu() menuitem_heading_4 = gtk.ImageMenuItem(_("Heading _4")) menuitem_heading_4.show() menuitem_heading_4.connect("activate", self.do_formatblock_h4) img = gtk.image_new_from_icon_name('stock_line-spacing-1.5', gtk.ICON_SIZE_MENU) menuitem_heading_4.set_image(img) menu_style.append(menuitem_heading_4) menuitem_heading_5 = gtk.ImageMenuItem(_("Heading _5")) menuitem_heading_5.show() menuitem_heading_5.connect("activate", self.do_formatblock_h5) img = gtk.image_new_from_icon_name('stock_list_enum-off', gtk.ICON_SIZE_MENU) menuitem_heading_5.set_image(img) menu_style.append(menuitem_heading_5) menuitem_heading_6 = gtk.ImageMenuItem(_("Heading _6")) menuitem_heading_6.show() menuitem_heading_6.connect("activate", self.do_formatblock_h6) img = gtk.image_new_from_icon_name('stock_list_enum-off', gtk.ICON_SIZE_MENU) menuitem_heading_6.set_image(img) menu_style.append(menuitem_heading_6) menuitem_separator5 = gtk.MenuItem() menuitem_separator5.show() menu_style.append(menuitem_separator5) menuitem_bulleted_list = gtk.ImageMenuItem(_("_Bulleted List")) menuitem_bulleted_list.show() menuitem_bulleted_list.connect("activate", self.do_insertunorderedlist) img = gtk.image_new_from_icon_name('stock_list_bullet', gtk.ICON_SIZE_MENU) menuitem_bulleted_list.set_image(img) menu_style.append(menuitem_bulleted_list) menuitem_numbered_list = gtk.ImageMenuItem(_("Numbered _List")) menuitem_numbered_list.show() menuitem_numbered_list.connect("activate", self.do_insertorderedlist) img = gtk.image_new_from_icon_name('stock_list_enum', gtk.ICON_SIZE_MENU) menuitem_numbered_list.set_image(img) menu_style.append(menuitem_numbered_list) menuitem_separator6 = gtk.MenuItem() menuitem_separator6.show() menu_style.append(menuitem_separator6) div1 = gtk.ImageMenuItem(_("Di_v")) div1.show() div1.connect("activate", self.do_formatblock_div) img = gtk.image_new_from_icon_name('stock_tools-hyphenation', gtk.ICON_SIZE_MENU) div1.set_image(img) menu_style.append(div1) address1 = gtk.ImageMenuItem(_("A_ddress")) address1.show() address1.connect("activate", self.do_formatblock_address) img = gtk.image_new_from_icon_name('stock_tools-hyphenation', gtk.ICON_SIZE_MENU) address1.set_image(img) menu_style.append(address1) #menuitem_formatblock_code = gtk.ImageMenuItem(_("_Code")) #menuitem_formatblock_code.show() #menuitem_formatblock_code.connect("activate", self.do_formatblock_code) # #img = gtk.image_new_from_icon_name('stock_text-monospaced', gtk.ICON_SIZE_MENU) #menuitem_formatblock_code.set_image(img) #menu_style.append(menuitem_formatblock_code) menuitem_formatblock_blockquote = gtk.ImageMenuItem(_("Block_quote")) menuitem_formatblock_blockquote.show() menuitem_formatblock_blockquote.connect("activate", self.do_formatblock_blockquote) img = gtk.image_new_from_icon_name('stock_list-insert-unnumbered', gtk.ICON_SIZE_MENU) menuitem_formatblock_blockquote.set_image(img) menu_style.append(menuitem_formatblock_blockquote) menuitem_formatblock_pre = gtk.ImageMenuItem(_("_Preformat")) menuitem_formatblock_pre.show() menuitem_formatblock_pre.connect("activate", self.do_formatblock_pre) img = gtk.image_new_from_icon_name('stock_text-quickedit', gtk.ICON_SIZE_MENU) menuitem_formatblock_pre.set_image(img) menu_style.append(menuitem_formatblock_pre) button1.set_menu(menu_style) ######################## ## 粗体按钮菜单 menu_format = gtk.Menu() menu_format.append(gtk.TearoffMenuItem()) menuitem_italic = gtk.ImageMenuItem("gtk-italic") menuitem_italic.show() menuitem_italic.connect("activate", self.do_italic) menu_format.append(menuitem_italic) menuitem_underline = gtk.ImageMenuItem("gtk-underline") menuitem_underline.show() menuitem_underline.connect("activate", self.do_underline) menu_format.append(menuitem_underline) menuitem_strikethrough = gtk.ImageMenuItem("gtk-strikethrough") menuitem_strikethrough.show() menuitem_strikethrough.connect("activate", self.do_strikethrough) menu_format.append(menuitem_strikethrough) separatortoolitem4 = gtk.SeparatorToolItem() separatortoolitem4.show() self.toolbar1.add(separatortoolitem4) toolbutton_bold = gtk.MenuToolButton(gtk.STOCK_BOLD) toolbutton_bold.set_label(_("Bold")) toolbutton_bold.set_tooltip_text(_("Bold")) toolbutton_bold.show() toolbutton_bold.set_stock_id(gtk.STOCK_BOLD) toolbutton_bold.connect("clicked", self.on_bold) toolbutton_bold.set_menu(menu_format) self.toolbar1.add(toolbutton_bold) ## 高亮颜色 toolbutton_hilitecolor = gtk.MenuToolButton("") toolbutton_hilitecolor.set_icon_name("stock_text_color_hilight") toolbutton_hilitecolor.set_label(_("Highlight")) toolbutton_hilitecolor.set_tooltip_text(_("Highlight")) toolbutton_hilitecolor.set_arrow_tooltip_markup(_("Select hilitecolor")) toolbutton_hilitecolor.set_menu(gtk.Menu()) toolbutton_hilitecolor.show() toolbutton_hilitecolor.connect("clicked", self.do_color_hilitecolor) ### 处理 ToolButton 箭头 on_color_select_hilitecolor = self.on_color_select_hilitecolor ib, mb = toolbutton_hilitecolor.get_children()[0].get_children() mb.connect("clicked", self.on_color_select_hilitecolor) self.toolbar1.add(toolbutton_hilitecolor) ## 清除格式 button1 = gtk.ToolButton() button1.set_icon_name("gtk-clear") button1.set_label(_("Clear format")) button1.set_tooltip_text(_("Clear format")) button1.show() button1.connect("clicked", self.do_removeformat) self.toolbar1.add(button1) ### 字体菜单按钮 #toolbutton_font = gtk.MenuToolButton("gtk-select-font") #toolbutton_font.set_label(_("Font")) #toolbutton_font.set_tooltip_text(_("Font")) #toolbutton_font.show() #toolbutton_font.set_menu(self.fontname_menu) ### 处理 gtk.MenuToolButton 按钮 #m = toolbutton_font #ib, mb = m.child.children() #mb.remove(mb.child) #ib.child.reparent(mb) #m.child.remove(ib) #self.toolbar1.add(toolbutton_font) ## ############### self.toolbar = gtk.HandleBox() self.toolbar.add(self.toolbar1) self.toolbar.show_all() self.vbox1.pack_start(self.toolbar, False, False, 0) ## 编辑区 #self.editport = gtk.Viewport() #self.editport.show() #self.editport.set_shadow_type(gtk.SHADOW_NONE) # #self.vbox1.pack_start(self.editport) ## self.notebox = gtk.Notebook() self.notebox.set_tab_pos(2) # 0, 1, 2, 3 -> left, top, right, bottom self.notebox.set_border_width(0) #self.notebox.popup_enable() self.notebox.set_property('homogeneous', 0) self.notebox.unset_flags(gtk.CAN_FOCUS) self.notebox.set_scrollable(True) self.notebox.connect("switch-page", self.on_mdi_switch_page) self.notebox.connect("button-press-event", self.on_mdi_menu) # 用 "button-release-event" 会不能中止事件向上传递 self.notebox.show() editbox = self.new_edit(self.editfile) editbox.show() self.notebox_insert_page(editbox) self.notebox.set_tab_reorderable(editbox, True) self.notebox.show_all() self.vbox1.pack_start(self.notebox) ## 搜索栏 self.findbar = gtk.HandleBox() self.findbar.set_shadow_type(gtk.SHADOW_OUT) self.findbox = gtk.HBox(False, 0) self.findbox.show() button_hidefindbar = gtk.Button() button_hidefindbar.set_tooltip_text(_("Close Findbar")) button_hidefindbar.show() button_hidefindbar.set_relief(gtk.RELIEF_NONE) button_hidefindbar.connect("clicked", self.hide_findbar) image113 = gtk.Image() image113.set_from_stock(gtk.STOCK_CLOSE, 1) image113.show() button_hidefindbar.add(image113) self.findbox.pack_start(button_hidefindbar, False, False, 0) self.entry_searchtext = gtk.Entry() self.entry_searchtext.show() self.entry_searchtext.connect("changed", self.do_highlight_text_matches) #self.entry_searchtext.set_property("primary-icon-stock", "gtk-go-back") #self.entry_searchtext.set_property("primary-icon-tooltip-text", _("Find Previous")) #self.entry_searchtext.set_property("secondary-icon-stock", "gtk-find") #self.entry_searchtext.set_property("secondary-icon-tooltip-text", _("Find Next")) self.entry_searchtext.set_property("primary-icon-stock", "gtk-find") self.entry_searchtext.set_property("primary-icon-tooltip-text", _("Find Next")) self.entry_searchtext.connect("icon-release", self.do_find_text) self.entry_searchtext.set_tooltip_text(_("Search text")) #self.entry_searchtext.set_flags(gtk.CAN_DEFAULT) #self.entry_searchtext.grab_focus() self.findbox.pack_start(self.entry_searchtext) button1 = gtk.Button() button1.set_tooltip_text(_("Find Previous")) button1.show() button1.set_relief(gtk.RELIEF_NONE) button1.connect("clicked", self.do_find_text_backward) image1 = gtk.Image() image1.set_from_stock(gtk.STOCK_GO_BACK, 4) image1.show() button1.add(image1) self.findbox.pack_start(button1, False, False, 0) button_search_text = gtk.Button(_("Find")) img = gtk.Image() img.set_from_stock("gtk-find", 4) img.show() button_search_text.set_image(img) button_search_text.set_tooltip_text(_("Find Next")) button_search_text.show() button_search_text.set_relief(gtk.RELIEF_NONE) button_search_text.connect("clicked", self.do_find_text) button_search_text.add_accelerator("clicked", self.accel_group, gtk.gdk.keyval_from_name("F3"), 0, gtk.ACCEL_VISIBLE) self.findbox.pack_start(button_search_text, False, False, 0) self.findbox.pack_start(gtk.VSeparator(), False, False, 3) self.entry_replace_text = gtk.Entry() self.entry_replace_text.show() self.entry_replace_text.set_tooltip_text(_("Replace text")) self.entry_replace_text.set_property("primary-icon-stock", "gtk-find-and-replace") self.entry_replace_text.set_property("primary-icon-tooltip-text", _("Replace")) self.findbox.pack_start(self.entry_replace_text) button_replace_text = gtk.Button() button_replace_text.set_tooltip_text(_("Replace")) button_replace_text.show() button_replace_text.set_relief(gtk.RELIEF_NONE) button_replace_text.connect("clicked", self.do_replace_text) alignment1 = gtk.Alignment(0.5, 0.5, 0, 0) alignment1.show() hbox2 = gtk.HBox(False, 0) hbox2.show() hbox2.set_spacing(2) image136 = gtk.Image() image136.set_from_stock(gtk.STOCK_FIND_AND_REPLACE, 4) image136.show() hbox2.pack_start(image136, False, False, 0) label1 = gtk.Label(_("Replace")) label1.show() hbox2.pack_start(label1, False, False, 0) alignment1.add(hbox2) button_replace_text.add(alignment1) self.findbox.pack_start(button_replace_text, False, False, 0) #self.findbox.pack_start(gtk.VSeparator(), False, False, 0) button2 = gtk.Button() button2.set_tooltip_text(_("Replace All")) button2.set_label(_("ReplaceAll")) button2.show() button2.set_relief(gtk.RELIEF_NONE) img = gtk.Image() img.set_from_stock("gtk-convert", 4) img.show() button2.set_image(img) button2.connect("clicked", self.do_replace_text_all) self.findbox.pack_start(button2, False, False, 0) self.findbar.add(self.findbox) self.vbox1.pack_start(self.findbar, False, False, 0) #self.edit.contextmenu.append(menuitem_style) #self.edit.connect("popup-menu", self._populate_popup) if create: self.window.add(self.vbox1) pass pass def mdi_get_tab_menu(self, editbox=None, windowslist=0): menu = gtk.Menu() menuitem_new = gtk.ImageMenuItem("gtk-new") menuitem_new.show() menuitem_new.connect("activate", self.on_new) menu.append(menuitem_new) menuitem_close = gtk.ImageMenuItem("gtk-close") menuitem_close.show() menuitem_close.connect("activate", self.close_tab, editbox) menu.append(menuitem_close) menu.append(gtk.MenuItem()) notebox = self.notebox for box in notebox.get_children(): menuitem = gtk.ImageMenuItem(box.edit.title) menuitem.set_image(gtk.image_new_from_stock("gtk-dnd", gtk.ICON_SIZE_MENU)) menuitem.connect("activate", self.notebox_set_current, box) menuitem.show() menu.append(menuitem) pass if windowslist and config.single_instance_mode: pass menu.show_all() return menu def on_accel_connect_group(self, accel_group, acceleratable, keyval, modifier): ## 按 Alt-1, Alt-2... 切换标签页 ## gtk.gdk.keyval_from_name('1') 为 49 num = keyval - 49 self.notebox.set_current_page(num) return def on_mdi_menu(self, widget, event, editbox=None, *args): #-print self, widget, event, editbox, args if event.button == 3: #menu = self.menu_file menu = self.mdi_get_tab_menu(editbox) menu.popup(None, None, None, event.button, event.time) return True elif ( ( event.type.value_name == "GDK_BUTTON_PRESS" and event.button == 2 ) or ( event.type.value_name == "GDK_2BUTTON_PRESS" and event.button == 1 ) ): # 标签上 中键/双击 关闭,空白处 中键/双击 新建 if editbox: self.close_tab(editbox) pass else: self.on_new() pass return True #box = self.notebox #label = box.get_tab_label( box.get_nth_page( box.get_current_page() ) ) return False def on_mdi_switch_page(self, notebook, page, page_num, *user_param): #-print 'on_mdi_switch_page:', notebook, page, page_num ## show/hide tabbar self.notebox.unset_flags(gtk.CAN_FOCUS) if self.notebox.get_n_pages() > 1: self.notebox.set_show_tabs(True) pass else: self.notebox.set_show_tabs(False) pass ## edit, linkview editbox = self.notebox.get_nth_page(page_num) self.editbox = editbox self.edit = editbox.edit self.linkview = editbox.linkview ## #self.edit.set_flags(gtk.CAN_DEFAULT) #if self.edit.editfile: self.window.set_title(os.path.basename(self.editfile) + ' - ' + Title) self.window.set_title(self.edit.title + ' - ' + Title) ## try: self.do_highlight_text_matches() except: pass pass def on_over_link(self, edit, alt, href): #-print edit, alt, href href = href or "" uri = edit.get_main_frame().get_uri() url = urllib2.unquote(uri) if "#" in href and uri.split('#', 1)[0] == href.split('#', 1)[0]: href = "#" + href.split('#', 1)[1] self.window.set_tooltip_text(href) pass def notebox_set_current(self, widget, editbox=None): editbox = editbox or widget # 考虑非事件的调用 num = self.notebox.page_num(editbox) self.notebox.set_current_page(num) self.window.present() return def notebox_set_label_text(self, editbox, text): #self.notebox.set_tab_label_text(editbox, text) self.notebox.set_menu_label_text(editbox, text) label = gtk.Label(text) label.show() box = gtk.EventBox() box.set_visible_window(0) box.connect("button-press-event", self.on_mdi_menu, editbox) box.add(label) self.notebox.set_tab_label(editbox, box) pass def notebox_insert_page(self, editbox): cn = self.notebox.get_current_page() n = self.notebox.insert_page(editbox, None, cn+1) self.notebox_set_label_text(editbox, editbox.edit.title) self.notebox.set_tab_reorderable(editbox, True) #self.notebox.show_all() self.notebox.set_current_page(n) ## #self.notebox.get_tab_label(editbox).connect("button-press-event", self.on_mdi_menu) return def new_edit(self, editfile): global new_num editbox = gtk.VBox() editbox.show() separator = gtk.HSeparator() separator.show() editbox.pack_start(separator, False, False) hpaned = gtk.HPaned() hpaned.set_border_width(0) hpaned.set_position(170) hpaned.show() editbox.pack_start(hpaned, True, True) ## 导航栏 vbox1 = gtk.VBox() label1 = gtk.Label(_("Navigation Pane")) label1.set_alignment(0, 0) vbox1.pack_start(label1, False, False) scrolledwindow1 = gtk.ScrolledWindow() scrolledwindow1.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrolledwindow1.show() scrolledwindow1.set_shadow_type(gtk.SHADOW_IN) import webkitlinkview linkview = webkitlinkview.LinkTextView() linkview.connect('url-clicked', self.on_title_clicked) linkview.connect('populate-popup', self._linkview_populate_popup) linkview.show() scrolledwindow1.add(linkview) editbox.linkview = linkview vbox1.pack_start(scrolledwindow1) vbox1.show_all() hpaned.pack1(vbox1, False, True) editbox.navigation_pane = vbox1 ## 编辑区 import webkitedit scrolledwindow2 = gtk.ScrolledWindow() scrolledwindow2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrolledwindow2.show() scrolledwindow2.set_shadow_type(gtk.SHADOW_IN) edit = webkitedit.WebKitEdit(editfile) edit.show() edit.connect("load-finished", self.on_load_finished) edit.connect("hovering-over-link", self.on_over_link) edit.set_flags(gtk.CAN_FOCUS) edit.set_flags(gtk.CAN_DEFAULT) self.window.present() scrolledwindow2.add(edit) editbox.edit = edit hpaned.pack2(scrolledwindow2, True, True) if editfile: edit.lastDir = os.path.dirname(editfile) edit.title = os.path.basename(editfile) self.add_recent(editfile) pass else: if config.mdi_mode or config.single_instance_mode: edit.title = _("[New Document] %s") % new_num new_num += 1 pass else: edit.title = _("[New Document]") pass editbox.connect("button-press-event", lambda *i: True) ## 中止鼠标按钮事件向上传递 gobject.idle_add(proc_webkit_color, edit, linkview) return editbox def _populate_popup(self, view, menu): pass def zoom(self, level): self.edit.set_zoom_level(level) pass def zoom_100(self, *args): self.edit.set_zoom_level(1.0) pass def zoom_in(self, *args): self.edit.zoom_in() pass def zoom_out(self, *args): self.edit.zoom_out() pass def _linkview_populate_popup(self, view, menu): # 检查是否有链接相关菜单项 href = "" if menu_find_with_stock(menu, 'gtk-open') > -1: href = view.get_main_frame().get_title() pass ## 取消原先的菜单 #menu.destroy() #menu = gtk.Menu() for i in menu.get_children(): menu.remove(i) pass ## 跳转到 if href: menuitem_jump_to = gtk.ImageMenuItem("gtk-jump-to") menuitem_jump_to.show() menuitem_jump_to.connect("activate", self.edit.go_anchor, href) menu.append(menuitem_jump_to) menuitem_select = gtk.ImageMenuItem(_("_Select this")) menuitem_select.set_image(gtk.image_new_from_stock(gtk.STOCK_SELECT_ALL, gtk.ICON_SIZE_MENU)) menuitem_select.show() menuitem_select.set_tooltip_markup(_("您也可以直接双击以选择该章节文字")) menuitem_select.connect("activate", self.edit.select_section, href) menu.append(menuitem_select) menu.append(gtk.MenuItem()) pass ## 更新目录 menuitem_update_contents = gtk.ImageMenuItem(_("Update _Contents")) menuitem_update_contents.show() menuitem_update_contents.connect("activate", self.view_update_contents) img = gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU) menuitem_update_contents.set_image(img) menu.append(menuitem_update_contents) menuitem_toggle_numbered_title = gtk.ImageMenuItem(_("Toggle _Numbered Title")) menuitem_toggle_numbered_title.show() menuitem_toggle_numbered_title.connect("activate", self.view_toggle_autonumber) img = gtk.image_new_from_stock(gtk.STOCK_SORT_DESCENDING, gtk.ICON_SIZE_MENU) menuitem_toggle_numbered_title.set_image(img) menu.append(menuitem_toggle_numbered_title) ## 缩放菜单 linkview = self.linkview menuitem_separator10 = gtk.MenuItem() menuitem_separator10.show() menu.append(menuitem_separator10) menuitem_zoom_in = gtk.ImageMenuItem(gtk.STOCK_ZOOM_IN) menuitem_zoom_in.connect("activate", lambda *i: linkview.zoom_in()) menuitem_zoom_in.show() menu.append(menuitem_zoom_in) menuitem_zoom_out = gtk.ImageMenuItem(gtk.STOCK_ZOOM_OUT) menuitem_zoom_out.connect("activate", lambda *i: linkview.zoom_out()) menuitem_zoom_out.show() menu.append(menuitem_zoom_out) menuitem_zoom_100 = gtk.ImageMenuItem(gtk.STOCK_ZOOM_100) menuitem_zoom_100.connect("activate", lambda *i: linkview.set_zoom_level(1.0)) menuitem_zoom_100.show() menu.append(menuitem_zoom_100) menu.show_all() pass def on_title_clicked(self, widget, href, type): if href.startswith('+'): self.edit.select_section(href.split('#', 1)[1]) return True href = href.split('#', 1)[1] self.edit.go_anchor(href) pass def on_load_finished(self, edit, *args): #-print 'on_load_finished:' self.view_update_contents() if edit._html == "": edit.set_saved() pass pass def close_tab(self, widget=None, editbox=None, *args): notebox = self.notebox if widget and 'edit' in widget.__dict__: editbox = widget pass if not editbox: n = notebox.get_current_page() editbox = notebox.get_nth_page(n) pass edit = editbox.edit linkview = editbox.linkview self.window.show() if not edit.is_saved(): ## r: 1, -1, 0 => yes, no, cancel r = gtkdialogs.savechanges(_("%s Save Changes?") % edit.title) if r == 1: filename = self.on_save() if not filename: return True pass elif r == 0: return True pass # 关闭标签 notebox.remove(editbox) edit.destroy() linkview.destroy() editbox.destroy() # 无标签时关闭窗口 if self.notebox.get_n_pages(): return True Windows.remove(self) gtk.gdk.threads_leave() self.window.destroy() if not Windows: gtk.main_quit() return def on_close(self, *args): '''关闭窗口 ''' #-print 'on_close:', self #@TODO: 退出时未保存提示 for i in range(self.notebox.get_n_pages()): self.close_tab() pass if self.notebox.get_n_pages(): return True try: Windows.remove(self) pass except: pass gtk.gdk.threads_leave() self.window.destroy() if not Windows: gtk.main_quit() pass def on_quit(self, *args): #-print 'on_quit:' windows = reversed(Windows) for window in windows: window.on_close() pass gtk.main_quit() pass def on_new(self, *args): #-print 'on_new:' return self.open("") def on_new_window(self, *args): '''打开新窗口 ''' if config.single_instance_mode: return MainWindow() else: return os.spawnvp(os.P_NOWAIT, sys.argv[0], ['gwrite']) pass def add_recent(self, filename): uri = 'file://' + filename self.recent.add_full(uri, {'mime_type':'text/html', 'app_name':'gwrite', 'app_exec':'gwrite', 'group':'gwrite'}) def open(self, filename=""): self.window.present() # mdi mode if config.mdi_mode: if filename: for editbox in self.notebox.get_children(): if editbox.edit.editfile == filename: self.notebox.set_current_page(self.notebox.page_num(editbox)) return pass pass editbox = self.new_edit(filename) self.notebox_insert_page(editbox) return # 如果当前空文档,则在当前窗口打开 if filename and self.edit.editfile == '' and self.edit.is_saved(): self.window.set_title(os.path.basename(filename) + ' - ' + Title) self.edit.lastDir = os.path.dirname(filename) self.edit.editfile = filename self.edit._html = "" if filename and os.access(filename, os.R_OK): self.edit.open(filename) self.add_recent(filename) pass pass elif config.single_instance_mode: MainWindow(editfile = filename) pass else: if filename: os.spawnvp(os.P_NOWAIT, sys.argv[0], ['gwrite', filename]) pass else: os.spawnvp(os.P_NOWAIT, sys.argv[0], ['gwrite']) pass pass pass def on_select_recent(self, menu): filename = menu. get_current_item().get_uri_display() #-print 'on_select_recent:', filename self.open(filename) pass def on_open(self, *args): #-print 'on_open:' filename = gtkdialogs.open(title=_('Open'), name_mimes=[ [_("Html Document"), "text/html"], [_("MS Doc Document"), "application/msword"], ]) if filename and os.access(filename, os.R_OK): self.open(filename) pass gtk.gdk.threads_leave() pass def on_save(self, *args): #-print 'on_save:' html = self.edit.get_html() if self.edit.editfile: filename = self.edit.editfile else: #current_name = _('新建文档') #current_name = '' current_name = get_doctitle(html) filename = gtkdialogs.save(title=_('Save'), name_mimes=[[_("Html Document"), "text/html"]], current_name=current_name,) if filename and not '.' in os.path.basename(filename): filename = filename + '.html' if filename: try: file(filename, 'w').write(html) pass except: gtkdialogs.warning(_("Unable to write to file.")) return False self.edit.lastDir = os.path.dirname(filename) if not self.edit.editfile: self.add_recent(filename) #添加到最近文件 self.editfile = filename self.edit.set_saved() self.window.set_title(os.path.basename(filename) + ' - ' + Title) ## 更新标签名 self.edit.editfile = filename self.edit.title = os.path.basename(filename) self.notebox_set_label_text(self.editbox, self.edit.title) pass gtk.gdk.threads_leave() return filename def on_save_as(self, *args): #-print 'on_save_as:' html = self.edit.get_html() #current_name = _('新建文档') #current_name = '' current_name = get_doctitle(html) filename = gtkdialogs.save(title=_('Save As'), name_mimes=[[_("Html Document"), "text/html"]], current_name=current_name, folder=self.edit.lastDir,) if filename and not '.' in os.path.basename(filename): filename = filename + '.html' if filename: try: file(filename, 'w').write(html) pass except: gtkdialogs.warning(_("Unable to write to file.")) return False self.add_recent(filename) #添加到最近文件 self.edit.lastDir = os.path.dirname(filename) pass gtk.gdk.threads_leave() pass def on_word_counts(self, *args): document = self.edit.get_text().decode('utf8') selection = self.edit.get_selection() #-print text #-print selection # 行: '', 文档, 选中范围 # 列: 字数及英文单词数, 字符数(含空格), 字符数(不含空格), 段落数, 行数, 英文单词, 中文字 text = document words_cn = len( re.findall(u'[\u4e00-\uffff]', text) ) words_en = len( re.findall(u'\\w+', text) ) words = words_cn + words_en characters_with_spaces = len(text) characters_no_spaces = len(''.join(text.split())) _lines = text.splitlines() lines = len(_lines) paragraphs = len([i for i in _lines if i]) ## text = selection s_words_cn = len( re.findall(u'[\u4e00-\uffff]', text) ) s_words_en = len( re.findall(u'\\w+', text) ) s_words = s_words_cn + s_words_en s_characters_with_spaces = len(text) s_characters_no_spaces = len(''.join(text.split())) _s_lines = text.splitlines() s_lines = len(_s_lines) s_paragraphs = len([i for i in _s_lines if i]) info = ( ("", _("Document"), selection and _("Selection")), (_("Words: "), words, selection and s_words, ), (_("Characters (with spaces): "), characters_with_spaces, selection and s_characters_with_spaces), (_("Characters (no spaces): "), characters_no_spaces, selection and s_characters_no_spaces), (_("Paragraphs: "), paragraphs, selection and s_paragraphs), (_("Lines: "), lines, selection and s_lines), (_("English words: "), words_en, selection and s_words_en), (_("Chinese characters: "), words_cn, selection and s_words_cn), ) #-print info gtkdialogs.infotablebox(_("Word Counts"), "%s" % self.edit.title, info) return def on_print(self, *args): #-print 'on_print:' self.edit.do_print() pass def do_undo(self, *args): #-print 'do_undo:' self.window.present() self.edit.do_undo() pass def do_redo(self, *args): #-print 'do_redo:' self.window.present() self.edit.do_redo() pass def do_cut(self, *args): #-print 'do_cut:' self.window.present() self.edit.do_cut() pass def do_copy(self, *args): #-print 'do_copy:' self.window.present() self.edit.do_copy() pass def do_paste(self, *args): #-print 'do_paste:' self.window.present() self.edit.do_paste() pass def do_paste_unformatted(self, *args): #-print 'do_paste_unformatted:' self.edit.do_paste_unformatted() return def do_delete(self, *args): #-print 'do_delete:' self.window.present() self.edit.do_delete() pass def do_selectall(self, *args): #-print 'do_selectall:' self.window.present() self.edit.do_selectall() pass def show_findbar(self, *args): #-print 'show_findbar:' self.findbar.show_all() self.entry_searchtext.grab_focus() self.do_find_text(self.entry_searchtext) pass def view_update_contents(self, *args): #-print 'view_update_contents:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_view_update_contents() ) pass def view_toggle_autonumber(self, *args): #-print 'view_toggle_autonumber:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_view_toggle_autonumber() ) pass def view_sourceview(self, *args): #-print 'view_sourceview:' self.window.present() ## 源码模式隐藏导航栏 #@NOTE 执行顺序和 idle_add 是为了避免闪烁 if not self.edit.get_view_source_mode(): ## 先转到源码模式,再 idle_add 隐藏导航条,以便显示变化平滑 self.edit.toggle_html_view() gobject.idle_add( self.editbox.navigation_pane.hide ) pass else: ## 先显示导航条,再 idle_add 转为所见所得模式,以便显示变化平滑 self.editbox.navigation_pane.show_all() gobject.idle_add( self.edit.toggle_html_view ) pass #self.edit.do_bodyhtml_view() pass def do_update_images(self, *args): #-print 'do_update_images:' self.window.present() self.edit.do_image_base64() pass def do_insertimage(self, *args): #-print 'do_insertimage:' src = gtkdialogs.open(title=_('InsertImage'), name_mimes=[[_("Image Files"), "image/*"]]) if src: self.edit.do_insertimage(src) pass def do_createlink(self, *args): #-print 'do_createlink:' ##print self.edit.get_link_message() link = gtkdialogs.inputbox(title=_('Create Link'), label=_('URL:'), text="") if link and link != "http://": self.edit.do_createlink(link) pass def do_inserthorizontalrule(self, *args): #-print 'do_inserthorizontalrule:' self.window.present() self.edit.do_inserthorizontalrule() pass def do_insert_table(self, *args): #-print 'do_insert_table:' cow,row = gtkdialogs.spinbox2(title=_('Insert Table'),label1=_('Rows:'),value1=3, label2=_('Cows:'),value2=3) self.edit.do_insert_table(cow, row) pass def do_insert_html(self, *args): #-print 'do_insert_html:' html = gtkdialogs.textbox(title=_('Insert Html'), text='') if html: self.edit.do_insert_html(html) pass def do_insert_latex_math_equation(self, *args): '''Insert Latex math equation ''' latex = gtklatex.latex_dlg() if latex: img = gtklatex.tex2html(latex) self.edit.do_insert_html(img) pass pass def do_insert_contents(self, *args): #-print 'do_insert_contents:' self.window.present() self.edit.do_insert_contents() pass def do_formatblock_p(self, *args): #-print 'do_formatblock_p:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_p() ) pass def do_formatblock_h1(self, *args): #-print 'do_formatblock_h1:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_h1() ) pass def do_formatblock_h2(self, *args): #-print 'do_formatblock_h2:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_h2() ) pass def do_formatblock_h3(self, *args): #-print 'do_formatblock_h3:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_h3() ) pass def do_formatblock_h4(self, *args): #-print 'do_formatblock_h4:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_h4() ) pass def do_formatblock_h5(self, *args): #-print 'do_formatblock_h5:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_h5() ) pass def do_formatblock_h6(self, *args): #-print 'do_formatblock_h6:' self.window.present() self.linkview.updatehtmllinks( self.edit.do_formatblock_h6() ) pass def do_insertunorderedlist(self, *args): #-print 'do_insertunorderedlist:' self.window.present() self.edit.do_insertunorderedlist() pass def do_insertorderedlist(self, *args): #-print 'do_insertorderedlist:' self.window.present() self.edit.do_insertorderedlist() pass def do_formatblock_div(self, *args): #-print 'do_formatblock_address:' self.window.present() self.edit.do_formatblock_address() pass def do_formatblock_address(self, *args): #-print 'do_formatblock_address:' self.window.present() self.edit.do_formatblock_address() pass def do_formatblock_code(self, *args): #-print 'do_formatblock_code:' self.window.present() self.edit.do_formatblock_code() pass def do_formatblock_blockquote(self, *args): #-print 'do_formatblock_blockquote:' self.window.present() self.edit.do_formatblock_blockquote() pass def do_formatblock_pre(self, *args): #-print 'do_formatblock_pre:' self.window.present() self.edit.do_formatblock_pre() pass def on_bold(self, *args): #-print 'on_bold:' self.window.present() self.edit.do_bold() pass def do_underline(self, *args): #-print 'do_underline:' self.window.present() self.edit.do_underline() pass def do_italic(self, *args): #-print 'do_italic:' self.window.present() self.edit.do_italic() pass def do_strikethrough(self, *args): #-print 'do_strikethrough:' self.window.present() self.edit.do_strikethrough() pass def do_font_fontname(self, widget, fontname): #-print 'do_font_fontname:', fontname self.window.present() self.edit.do_font_fontname(fontname) pass def do_fontsize_1(self, *args): #-print 'do_fontsize_1:' self.window.present() self.edit.do_fontsize_11() pass def do_fontsize_2(self, *args): #-print 'do_fontsize_2:' self.window.present() self.edit.do_fontsize_2() pass def do_fontsize_3(self, *args): #-print 'do_fontsize_3:' self.window.present() self.edit.do_fontsize_3() pass def do_fontsize_4(self, *args): #-print 'do_fontsize_4:' self.window.present() self.edit.do_fontsize_4() pass def do_fontsize_5(self, *args): #-print 'do_fontsize_5:' self.window.present() self.edit.do_fontsize_5() pass def do_fontsize_6(self, *args): #-print 'do_fontsize_6:' self.window.present() self.edit.do_fontsize_6() pass def do_fontsize_7(self, *args): #-print 'do_fontsize_7:' self.window.present() self.edit.do_fontsize_7() pass def do_color_forecolor(self, *args): #-print 'on_color_forecolor:' if "forecolor" in self.__dict__: self.edit.grab_focus() self.edit.do_color_forecolor(self.forecolor) pass else: self.on_color_select_forecolor() pass pass def on_color_select_forecolor(self, *args): #-print 'on_color_select_forecolor:' color = gtkdialogs.colorbox() if color: self.forecolor = color self.edit.do_color_forecolor (color) pass pass def do_color_hilitecolor(self, *args): #-print 'do_color_hilitecolor:' if "hilitecolor" in self.__dict__: self.edit.grab_focus() self.edit.do_color_hilitecolor(self.hilitecolor) pass else: self.on_color_select_hilitecolor() pass pass def on_color_select_hilitecolor(self, *args): #-print 'on_color_select_hilitecolor:', args # 处理 gtk.MenuToolButton 箭头重复事件 if self.__dict__.get('_on_color_select_hilitecolor'): return True self._on_color_select_hilitecolor = 1 color = gtkdialogs.colorbox() self._on_color_select_hilitecolor = 0 if color: self.hilitecolor = color self.edit.do_color_hilitecolor(color) return False def do_removeformat(self, *args): #-print 'do_removeformat:' self.window.present() self.edit.do_removeformat() pass def do_justifyleft(self, *args): #-print 'do_justifyleft:' self.window.present() self.edit.do_justifyleft() pass def do_justifycenter(self, *args): #-print 'do_justifycenter:' self.window.present() self.edit.do_justifycenter() pass def do_justifyfull(self, *args): #-print 'do_justify:' self.window.present() self.edit.do_justifyfull() pass def do_justifyright(self, *args): #-print 'do_justifyright:' self.window.present() self.edit.do_justifyright() pass def do_indent(self, *args): #-print 'do_indent:' self.window.present() self.edit.do_indent() pass def do_outdent(self, *args): #-print 'do_outdent:' self.edit.do_outdent() pass def do_subscript(self, *args): #-print 'do_subscript:' self.window.present() self.edit.do_subscript() pass def do_superscript(self, *args): #-print 'do_superscript:' self.window.present() self.edit.do_superscript() pass def on_about(self, *args): #-print 'on_about:' authors = [ "Jiahua Huang ", "Aron Xu ", ] about = gobject.new(gtk.AboutDialog, name=_("GWrite"), program_name=_("GWrite"), logo_icon_name="gwrite", version=__version__, copyright=_("Copyright (C) 2009-2010 Jiahua Huang, Aron Xu"), comments=_("Simple GTK+ HTML5 Rich Text Editor"), license="LGPLv3+", website="http://gwrite.googlecode.com/", website_label="gwrite.googlecode.com", authors=authors) #about.set_transient_for(self.window) about.run() about.destroy() pass def hide_findbar(self, *args): #-print 'hide_findbar:' self.findbar.hide() pass def do_highlight_text_matches(self, *args): text = self.entry_searchtext.get_text() if text: self.edit.unmark_text_matches() matches = self.edit.mark_text_matches(text, 0, 0) self.edit.set_highlight_text_matches(1) self.entry_searchtext.set_tooltip_markup(_("%s matches") % matches) pass else: self.edit.unmark_text_matches() self.edit.set_highlight_text_matches(0) self.entry_searchtext.set_tooltip_text(_("Search text")) pass pass def do_find_text_backward(self, *args): #-print 'do_find_text_backward:' text = self.entry_searchtext.get_text() if not text: return self.edit.do_find_text_backward(text) pass def do_find_text(self, *args): #-print 'do_find_text:' # 点击前面的图标为向上查找 #if self.entry_searchtext.get_pointer()[0] < 30: # return self.do_find_text_backward() text = self.entry_searchtext.get_text() if text: self.edit.do_find_text(text) pass def do_replace_text(self, *args): #-print 'do_replace_text:' ffindtext = self.entry_searchtext.get_text() replacetext = self.entry_replace_text.get_text() if ffindtext: self.edit.do_replace_text(ffindtext, replacetext) pass def do_replace_text_all(self, *args): #-print 'do_replace_text_all:' ffindtext = self.entry_searchtext.get_text() replacetext = self.entry_replace_text.get_text() if ffindtext: self.edit.do_replace_text_all(ffindtext, replacetext) pass def get_custom_widget(self, id, string1, string2, int1, int2): w = gtk.Label(_("(custom widget: %s)") % id) return w ##cmd test usage = _('''GWrite Usage: gwrite [OPTION...] [FILE...] - Edit html files Options: -h, --help Show help options -v, --version Show version information ''') def openedit(filename=""): '''MainWindow() 的包装 要 return False 以免 gtk.idle_add, gtk.timeout_add 重复执行 ''' Windows[0].open(filename) return False def _listen(s): '''监听 unix socket ''' #-print 'listen:', s while 1: conn, addr = s.accept() rev = conn.recv(102400) for i in rev.split('\n'): #-print 'Open:', i gobject.idle_add(openedit, i) pass pass pass def main(): '''处理命令行 ''' import os, sys import socket ## 处理命令行参数 import getopt config.load() gtk.gdk.threads_init() try: opts, args = getopt.getopt(sys.argv[1:], 'vh', ['version', 'help']) pass except: print usage return for o, v in opts: if o in ('-h', '--help'): print usage return elif o in ('-v', '--version'): print __version__ return pass ## 要 打开的文件 editfiles = [ os.path.abspath(i) for i in args ] ## 单实例模式 if config.single_instance_mode: ## 设 profdir 和 ctlfile profdir = config.profdir ## 单实例运行, 尝试用已打开 GWrite ctlfile = config.ctlfile try: ## 已打开 GWrite 的情况 s = socket.socket(socket.AF_UNIX) s.connect(ctlfile) s.send('\n'.join(editfiles)) #-print 'sent:', editfiles return except: #raise #-print 'new:' pass ## 监听 socket s = socket.socket(socket.AF_UNIX) if os.access(ctlfile, os.R_OK): os.remove(ctlfile) s.bind(ctlfile) s.listen(1) thread.start_new_thread(_listen, (s,)) pass ## 打开文件 edit = MainWindow( editfiles[0:] and editfiles[0] or '' ) for i in editfiles[1:]: i = os.path.abspath(i) edit.open(i) pass ## 处理 Gtk 图标主题 settings = gtk.settings_get_default( ) if settings.get_property( 'gtk-icon-theme-name' ) == 'hicolor': settings.set_property( 'gtk-icon-theme-name', 'Tango') pass ## 处理额外图标路径 icon_theme = gtk.icon_theme_get_default() icon_dir = os.path.dirname(__file__) + '/icons' icon_theme.append_search_path(icon_dir) ## gtk.gdk.threads_enter() gtk.main() gtk.gdk.threads_leave() if __name__ == '__main__': main() gwrite-0.5.1/gwrite/i18n.py0000644000175000017500000000072511534726454014147 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: # Author: Huang Jiahua # License: LGPLv3+ # Last modified: app = 'gwrite' import os, sys import gettext if os.path.isdir(os.path.dirname(sys.argv[0]) + '/../build/mo'): gettext.install(app, os.path.dirname(sys.argv[0]) + '/../build/mo', unicode=True) else: gettext.install(app, unicode=True) if __name__=="__main__": print _('') gwrite-0.5.1/gwrite/icons/0000755000175000017500000000000011534726454014125 5ustar aronarongwrite-0.5.1/gwrite/icons/stock_font-size.png0000644000175000017500000000102011534726454017745 0ustar aronaronPNG  IHDRabKGDIDATxڥ-bQA`44_4X4N?` #9Nwp]W\ו,Y< 1ư^QJAk}}l۾p5%r9ǹq fs.{m 'ZSVbL&Rضve۱mH wn6J%Zk! Bj \Wr)Já$IY,e>nr,T*9b@6 <~t:MF)EPjQ,Mt]r!H , Ft:cR&zR)& шt~g6}x曉J),ˢ^fZƲ,2 qe (@<C|hx<~Z<~ODj^ =X|*IENDB`gwrite-0.5.1/gwrite/icons/stock_insert-header.png0000644000175000017500000000051611534726454020572 0ustar aronaronPNG  IHDRabKGDIDATxڕ1n0DP Dr\"F9v49@A*nBabidi3`$/#k4bcLӴV2ϳ,9qI] 3J rYR$$DYM`eqoEq;n$p1c (^cx?۶ m p8,W﯆7IIENDB`gwrite-0.5.1/gwrite/icons/stock_insert-rule.png0000644000175000017500000000025611534726454020312 0ustar aronaronPNG  IHDRabKGDcIDATxc`r3200!ß/w_o0i30000\A6_1|(_S `0$3 iIENDB`gwrite-0.5.1/gwrite/icons/stock_insert-table.png0000644000175000017500000000046711534726454020436 0ustar aronaronPNG  IHDRabKGDIDATxS0$ 0&_$,$ 1 AMp=qy}&;s:vg |L;xoqr,KK8&~)0q6#{W}߷`!@ʜsxڶHeU.$Ib(P{\8۶}բa*4MR=HDdiijh}#s(إ)uh0 Peѳp ٥hַIENDB`gwrite-0.5.1/gwrite/icons/stock_insert_image.png0000644000175000017500000000112111534726454020477 0ustar aronaronPNG  IHDRagAMA abKGDC pHYs  ~tIME 4;Z%IDATxڝ1ha/wREJ!b]QBq 8 "*t "f#AC,A""%R>XWP 6RtEhJC|hTP(6Q[qzyj};'g,@ԩ'f WKLL{Z!ȋEQ\p}އ~`x<")rċXӡ$ZXra٬<9NV.nG?*f$ovI~~ H!ņ ĵ[d$&KiWʒpT2]^n%gU׻x 9s chZݍdz0I=ZPfB; 8DpN-poZL+IENDB`gwrite-0.5.1/gwrite/icons/stock_line-spacing-1.png0000644000175000017500000000044211534726454020545 0ustar aronaronPNG  IHDRabKGDIDATxڥ;j@E/2 <u]g{۲,;,`1F1ZJRJֶg{8NYYb ^+EAUUz QD 9]9pΙ?.ooa6&IENDB`gwrite-0.5.1/gwrite/icons/stock_link.png0000644000175000017500000000062311534726454016774 0ustar aronaronPNG  IHDRabKGDHIDATxڕ?KANbQI}ۤR_kemL ;J\l6 ΁)7Û'"E*]ˀ9pXTl^VkٻM΁K^Y. #F"2H&M4uV# C>"BZIl2̀R*b@ qEA[f ؍Fcm/c`: <5u73uxԢm eE煹\nDd,"hrw 8f"8NV0-p ,ptoNp̖IENDB`gwrite-0.5.1/gwrite/icons/stock_list-insert-unnumbered.png0000644000175000017500000000064111534726454022456 0ustar aronaronPNG  IHDRagAMA abKGD pHYs  ~tIME  3IDATxڥ1n@E,tTn8@*8D4N&2&R![ML;BhG4xVkZkE à08::9UU)@m,sl9a*EAc8 M9ϧHdzyz,s)0'R$7}@&A9"Ben!>_.7hίaayLjnK@ua]ii~%ꉳN2^\IENDB`gwrite-0.5.1/gwrite/icons/stock_list_bullet.png0000644000175000017500000000055611534726454020366 0ustar aronaronPNG  IHDRabKGD#IDATxڥ@ R+,^RXKoS,]N甽hն Bϟ |? t:VZ;9Mh4WG('7Ƽs&"(~GD-l6mt]8~9 Z5̲Gn10eYN ,k;t?Z 9u! +4kD4MZr$W؏Ӵ\.hdN` 0WyXˑ?Qo~IENDB`gwrite-0.5.1/gwrite/icons/stock_list_enum-off.png0000644000175000017500000000060611534726454020607 0ustar aronaronPNG  IHDRagAMA abKGD pHYs  ~tIME -mIDATxڥAj0E(o &W(Y\ݤ !P!*+`-FiUBс_3<h^'9u< eeY{{ !hAS`+:I`˭k .%"m{Ev7< sD]it9cL`LJ#WU&&4gq A4n@D8LӔc eY~%Vkt54s.{EQ`wkmZ ͆'*IENDB`gwrite-0.5.1/gwrite/icons/stock_list_enum-restart.png0000644000175000017500000000104111534726454021513 0ustar aronaronPNG  IHDRagAMA abKGD pHYs  ~tIME /&*IDATxڥkSQ?EtLln]]$P%$!/@Giߞ)[t-IpLnT8]׆i=y^?3wHjj:42ͲLpZl6T*!\]~?GQDEz\P1fe}SYyF(rudvl<8V9[֖!?oN; í&@s~d2!I*rΩśnG$V1J0 sNgY鯳Ozq{:u<k^tBeh9+f}5O~'"`0@D""A@ {;m1B'i윦){}hǟ>\1apIENDB`gwrite-0.5.1/gwrite/icons/stock_list_enum.png0000644000175000017500000000065411534726454020042 0ustar aronaronPNG  IHDRabKGDaIDATxڥO"1/)tuӫ9..z6-Ean 9Cm];xqSB**l|$Kޟ~7 >t:Ekmƺ;pE\G} !B<x Zk^HJpH‡5~O(vH`Z[״Hy'Y5J{ِ:뺦<[&ςீs8Et:e<ٕ~M( f& Yu@Dl6n7. 9yzFUk1p8"2-JZk ڧPDH*irYۓ?1~p^4WIENDB`gwrite-0.5.1/gwrite/icons/stock_subscript.png0000644000175000017500000000074311534726454020060 0ustar aronaronPNG  IHDRabKGDIDATxڥS"An0qcMAAc1;=;É dS 4sQGMuνc5j 3>_|J)*kc 1LIZKk-}'gJ){!ZJ8գ`!]vVcnQ,\.U^ja4AJNBqnS@57 0dVl6jb\pxd 6MqLԫ1arXu]zG.' O(k F`( p8|>G;dٗ+$InJt^,J\.w)4ZKq{.63cAzj )5 o [?Ie)fIENDB`gwrite-0.5.1/gwrite/icons/stock_superscript.png0000644000175000017500000000075511534726454020430 0ustar aronaronPNG  IHDRabKGDIDATxڥ?Abi!ZB`{gxAWRs [ZYm%X b#ظ-n&H ={g|~ O l60 % C(8%cID$he: ÐR*0b~P(.J)<X)@PHoͮ>64 ^GVKq=ϻsAE8CTb^v S7r2h4hXc:NjXv8#z]l61MSN4TZDQ$AjJj²,L|x\H$Ap8}>J)F` Zk9*\<eJ\'4cZ|k5a~?L&|mim^'\5/oKsrIENDB`gwrite-0.5.1/gwrite/icons/stock_text-monospaced.png0000644000175000017500000000053011534726454021146 0ustar aronaronPNG  IHDRabKGD IDATxڝn03c*suI>D>/BltIIԨ-}w>T0#ހWiZZumb&IyugZj{DdƘ,I + Es{zar(kie"Be1?RY*|>c!s[0 V8 3y75m IUUkrYEQx<{qv8x GQ{Zxf ٶnq۶pu\' WY$&IENDB`gwrite-0.5.1/gwrite/icons/stock_text-quickedit.png0000644000175000017500000000033411534726454021002 0ustar aronaronPNG  IHDRagAMA abKGD pHYs  ~tIME) /YIDATxc @& ! ?GBct NGbtq6cd0 ]- 0$K[K!IENDB`gwrite-0.5.1/gwrite/icons/stock_text_color_hilight.png0000644000175000017500000000110011534726454021720 0ustar aronaronPNG  IHDRagAMA abKGD pHYs  ~tIME <<IDATxڥOkSAHE,tKq!ХKq!BhuG_D1D]KT31b /.9wܙ(o@k`x[VeVI, MSi,˔esrΩRVz]FCfSVKRI岢(RUS d& 0k*Bށ 1yc̼`vpl< | G>W~e2$Q'O&u7a ]џ 4hf*1)xf?<4U Et?+Nv y Nהּ/5_7 KC`& [pՆ>pJ^sNqyʍauзc\@xO.{(0x]މ_*l}C)E!4#Vb:kH 0 v!f28o7y>֚LgoV9u(DJ^BɓF!VKJA '^OXk@}VHSk$ř '_x:婡80$"NM0Di~(IENDB`gwrite-0.5.1/gwrite/icons/stock_view-html-source.png0000644000175000017500000000121311534726454021245 0ustar aronaronPNG  IHDRagAMA abKGD pHYs  ~tIME -'SIDATxڍ1hSQ?k* :DKP0$&bAAD(:7H*CqIIW$/%8Ab4g>,*]ILL-=pss'܀D?l^7ZBq[zhZ+}JN?gNB\D">*/qC._8b0;75šU4Mj| \zka/^s{ד=&o"f/ʻ5\_TěהeYʲ,zNjA{7*|/i3ϱC.趠gGq 3'4}ckߨ(j1NLsS>Ύ۸rn Alf1J), )%h4ez"^RidY4MT*D0 c }Trm8N<NO>'Ln,N;a&BL0 (Lf@σFw !bcuv! P5&s'';o.3?{]IENDB`gwrite-0.5.1/gwrite/webkitedit.py0000644000175000017500000012607611534726454015533 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: # Author: Huang Jiahua # License: LGPLv3+ # Last modified: __version__ = '0.5.1' import gtk, gobject import webkit import jswebkit import gtklatex import urllib2 import os, errno import re import docfilter try: import i18n except: from gettext import gettext as _ def format_html(html): '''给 html 添加适当换行 ''' html = re.sub('\n?\ ?<(address|blockquote|center|dir|div|dl|fieldset|form|h1|h2|h3|h4|h5|h6|hr|isindex|menu|noframes|noscript|ol|p|pre|table|ul|dd|dt|frameset|li|tbody|td|tfoot|th|thead|tr)([^>]*?)>', '\n<\\1\\2>', html) html = re.sub(']*?)>\ ?\n?', '\n', html) html = re.sub('\n?<(img|hr|br)([^>]*?)>\n?', '\n<\\1\\2>\n', html) ## 对于 pre,合并相邻
,将 
 内的 
转为 "\n" html = re.sub('\n?
\s*
\n?', '', html)
    html = re.sub('
[^\0]*?
', lambda m: re.sub('\n?
\n?', '\\n', m.group()), html) return html def stastr(stri): '''处理字符串的 ' " ''' return stri.replace("\\","\\\\").replace(r'"',r'\"').replace(r"'",r"\'").replace('\n',r'\n') def get_end_ids(start): '''获取可能的下一个 id @note: 为了符合 w3 的 id 命名,在数字前加上字母 g 前缀 >>> get_end_ids('g5.1.1.1') ['g5.1.1.2', 'g5.1.2', 'g5.2', 'g6'] ''' start = start.replace('g', '') ids = start.split('.') ends = [] for i in range(1, len(ids)+1): end = int(ids[-i])+1 end = '.'.join(ids[:-i] + [str(end)]) ends.append('g' + end) pass return ends def textbox(title='Text Box', label='Text', parent=None, text=''): """display a text edit dialog return the text , or None """ dlg = gtk.Dialog(title, parent, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK )) dlg.set_default_size(500,500) #lbl = gtk.Label(label) #lbl.set_alignment(0, 0.5) #lbl.show() #dlg.vbox.pack_start(lbl, False) gscw = gtk.ScrolledWindow() gscw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) textview=gtk.TextView() textview.set_wrap_mode(gtk.WRAP_WORD_CHAR) buffer = textview.get_buffer() if text: buffer.set_text(text) #textview.show() gscw.add(textview) #gscw.show() dlg.vbox.pack_start(gscw) dlg.show_all() resp = dlg.run() text=buffer.get_text(buffer.get_start_iter(),buffer.get_end_iter()) dlg.destroy() if resp == gtk.RESPONSE_OK: return text return None def menu_find_with_stock(menu, stock): '''查找菜单中对应 stock 的菜单项位置 ''' n = 0 for i in menu.get_children(): try: if i.get_image().get_stock()[0] == stock: return n except: pass n += 1 pass return -1 BLANKHTML='''


''' class WebKitEdit(webkit.WebView): '''Html Edit Widget ''' def __init__(self, editfile=''): '''WebKitEdit.__init__ ''' webkit.WebView.__init__(self) self.set_property('can-focus', True) self.set_property('can-default', True) self.set_full_content_zoom(1) self.write_html(BLANKHTML) self.lastDir = '' self.editfile = editfile if editfile and os.access(editfile, os.R_OK): self.open(editfile) self.lastDir = os.path.dirname(editfile) pass else: pass self.set_editable(1) #self.do_editable() self.connect("load-finished", self.do_editable) # 确保 document.body 已经准备好了 self._html = "" self.connect("navigation-requested", self.on_navigation_requested) self.connect("new-window-policy-decision-requested", self.on_new_window_policy_decision_requested) self.connect_after("populate-popup", self.populate_popup) self.connect("script-prompt", self.on_script_prompt) ## 允许跨域 XMLHttpRequest,以便 base64 内联图片 settings = self.get_settings() settings.set_property('enable-xss-auditor', False) settings.set_property('enable-universal-access-from-file-uris', True) settings.set_property('enable-file-access-from-file-uris', True) settings.set_property('enable-page-cache', True) settings.set_property('javascript-can-access-clipboard', True) settings.set_property('tab-key-cycles-through-elements', False) ## pass def open(self, editfile): '''打开文件 ''' self.editfile = editfile ## 导入 .doc if re.match('.*\.doc', editfile, re.I): self.editfile = editfile[:-4] + '.html' editfile = docfilter.doc2html(editfile) pass ## 导入 .odf elif re.match('.*\.odf', editfile, re.I): pass ## 导入 .rtf elif re.match('.*\.rtf', editfile, re.I): pass ## 打开 html webkit.WebView.open(self, editfile) pass def ctx(self, *args): '''获取 javascript ctx 对象 ''' ctx = jswebkit.JSContext(self.get_main_frame().get_global_context()) return ctx def eval(self, js): '''用 ctx 对象执行 javascript ''' return self.ctx().EvaluateScript(js) def get_html(self, *args): '''获取 HTML 内容 ''' if not self.get_view_source_mode(): self.execute_script('guesstitle();') self.do_image_base64() html = self.ctx().EvaluateScript('document.documentElement.innerHTML') html = format_html(html) return '\n\n%s\n\n' % html else: text = self.eval(''' html = document.body.innerHTML; html = html.replace(/td>\\n', '\n', text) text = text.replace(' \n', '\n') text = format_html(text) return text def get_section(self, *args): #@TODO: 用于查看章节字数等 js = ''' var range = document.createRange(); range.setStart(startNode, startOffset); range.setEnd(endNode, endOffset); ''' pass def get_selection(self, *args): '''获取选中区域的文本 ''' text = self.ctx().EvaluateScript(''' document.getSelection().toString(); ''') return text def get_text(self, *args): '''获取纯文本内容 处理过换行 ''' text = self.ctx().EvaluateScript(''' //text = document.body.textContent; html = document.body.innerHTML; html = html.replace(/ -1: menu.insert(menuitem_paste_unformatted, n+1) pass pass return False def select_section(self, widget, anc=""): '''在编辑区选中 id 对应章节文字 ''' if not anc: anc = widget start_id = anc.replace('#', '') end_ids = get_end_ids(start_id) #-print 'select_section:', start_id, end_ids self.go_anchor(anc) self.eval(''' //document.execCommand("selectall", false, false); start = document.getElementById("%s"); ids = %s; for (var i=0; i([^\0]*)''', html)+[""])[0] #body = re.sub(r'''[^\0]*''', '', html) #self.execute_script(r''' # document.body.innerHTML="%s"; # document.getElementsByTagName("head")[0].innerHTML="%s"; # '''% (stastr(body), stastr(head))) #pass def update_bodyhtml(self, html): '''更新正文 html ''' #print 'WebKitEdit.update_bodyhtml:' self.execute_script(r''' document.body.innerHTML="%s"; '''%stastr(html)) pass def do_editable(self, *args): '''set editable ''' #@TODO: 加入更新标题,更新目录 js 函数 #-print 'WebKitEdit.set_editable:' #cmd = r''' document.documentElement.contentEditable="true"; ''' self.set_editable(1) cmd = r''' /*document.documentElement.contentEditable="true";*/ /*document.body.contentEditable="true";*/ document.execCommand("useCSS",false, true); /* 处理标题 */ function guesstitle(){ if( (t=document.getElementsByTagName("title")) && (title=t[0].textContent) ){ return title; }else if( (h1=document.getElementsByTagName("h1")) && h1.length>0 ){ title=h1[0].textContent; } else { //p = document.createElement('pre'); //p.innerHTML = document.body.innerHTML.replace(//g, '>\n\n'); //title = p.textContent.replace(/^\s+/g, '').split('\n')[0]; title = document.body.textContent.split('\n')[0]; } if(! document.getElementsByTagName("title") ){ t = document.createElement('title'); t.textContent=title; document.getElementsByTagName("head")[0].appendChild(t); }else{ document.getElementsByTagName("title")[0].textContent=title; } }; /* 目录处理 */ function getheads(){ /* 取得所有 heading 标签到 heads */ tags = document.getElementsByTagName("*"); heads = new Array(); for (var i=0; i' + getiname(tt, name) + '\n'; break; case "H2": tt = ''; h2 += 1; h3 = 0; h4 = 0; h5 = 0; h6 = 0; tt += String(h1) + '.' + h2; inode.id = "g" + tt; inode.textContent = getiname(tt, name); tdir += ' '; tdir += '' + getiname(tt, name) + '\n'; break; case "H3": tt = ''; h3 += 1; h4 = 0; h5 = 0; h6 = 0; tt += String(h1) + '.' + h2 + '.' + h3; inode.id = "g" + tt; inode.textContent = getiname(tt, name); tdir += ' '; tdir += '' + getiname(tt, name) + '\n'; break; case "H4": tt = ''; h4 += 1; h5 = 0; h6 = 0; tt += String(h1) + '.' + h2 + '.' + h3 + '.' +h4; inode.id = "g" + tt; inode.textContent = getiname(tt, name); tdir += ' '; tdir += '' + getiname(tt, name) + '\n'; break; case "H5": tt = ''; h5 += 1; h6 = 0; tt += String(h1) + '.' + h2 + '.' + h3 + '.' + h4 + '.' + h5; inode.id = "g" + tt; inode.textContent = getiname(tt, name); tdir += ' '; tdir += '' + getiname(tt, name) + '\n'; break; case "H6": tt = ''; h6 += 1; tt += String(h1) + '.' + h2 + '.' + h3 + '.' + h4 + '.' + h5 + '.' + h6; inode.id = "g" + tt; inode.textContent = getiname(tt, name); tdir += ' '; tdir += '' + getiname(tt, name) + '\n'; break; } } pre = document.createElement('pre'); pre.innerHTML = tdir; tdir = pre.innerHTML; return tdir; } function updatedir(){ if( i = document.body.getAttribute("orderedheadings")){ autonu = i; } dirhtml = getdir(); if (t=document.getElementById("toctitledir")){ t.innerHTML = dirhtml; } return dirhtml; }; function randomChar(l) { var x="0123456789qwertyuioplkjhgfdsazxcvbnm"; var tmp=""; for(var i=0;i< l;i++) { tmp += x.charAt(Math.ceil(Math.random()*100000000)%x.length); } return tmp; } function uptex(img){ img.id = 'mimetex_' + randomChar(5); prompt("_#uptex:"+img.id, img.alt); } window.focus(); ;''' self.execute_script(cmd) pass def do_image_base64(self, *args): '''convert images to base64 inline image see http://tools.ietf.org/html/rfc2397 ''' gtk.gdk.threads_leave() # 修正线程问题 self.execute_script(r''' var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; function encode64(input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; do { chr1 = input.charCodeAt(i++) & 0xff; chr2 = input.charCodeAt(i++) & 0xff; chr3 = input.charCodeAt(i++) & 0xff; enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); } while (i < input.length); return output; }; /*netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");*/ for (var i=document.images.length-1; i+1; i--){ img = document.images[i]; if(img.src && !img.src.match(/^data:/)){ mx = new XMLHttpRequest(); mx.open("GET", img.src, false); mx.overrideMimeType('text/plain; charset=x-user-defined'); mx.send(null); if (mx.responseText && (mx.status==200 || mx.status==0) ){ img.setAttribute('uri', img.src); img.src = "data:image;base64," + encode64(mx.responseText); }; } }; ; ''') pass def set_visual_view(self, visual=True): '''切换所见所得模式 ''' if visual: if self.get_view_source_mode(): self.toggle_html_view() pass else: if not self.get_view_source_mode(): self.toggle_html_view() pass pass pass __prev_visual_html = '' __prev_source_html = '' def toggle_html_view(self, *args): '''查看源码 ''' #print 'WebKitEdit.toggle_html_view:' ## 转换模式会修改 html 源码,所以得判断下可有保存 ## 从所见所得模式转到源码模式 if not self.get_view_source_mode(): html = self.get_html() self.__prev_visual_html = html is_saved = self.is_saved() self.set_view_source_mode(1) self.reload() self.update_html(html) def do_is_saved(): if is_saved: self.__prev_source_html = self.get_html() pass else: self.__prev_source_html = '' pass gobject.idle_add(do_is_saved) pass ## 从源码模式转到所见所得模式 else: html = self.get_html() self.set_view_source_mode(0) self.reload() if self.__prev_source_html == html: self.update_html(self.__prev_visual_html) gobject.idle_add(self.set_saved) pass else: self.update_html(html) pass pass return def do_print(self, *args): '''打印 ''' #print 'WebKitEdit.do_print:' self.execute_script('print(); ') pass def do_undo(self, *args): '''撤销 ''' #print 'WebKitEdit.do_undo:' self.execute_script(' document.execCommand("undo", false, false); ') def do_redo(self, *args): '''重做 ''' #print 'WebKitEdit.do_redo:' self.execute_script(' document.execCommand("redo", false, false); ') def do_cut(self, *args): '''剪切 ''' #print 'WebKitEdit.do_cut:' self.cut_clipboard() def do_copy(self, *args): '''复制 ''' #print 'WebKitEdit.do_copy:' self.copy_clipboard() def do_paste(self, *args): '''粘贴 ''' #print 'WebKitEdit.do_paste:' #self.execute_script(' document.execCommand("paste", false, false); ') self.paste_clipboard() def do_paste_unformatted(self, *args): '''无格式粘贴 ''' #-print 'do_paste_unformatted:' text = gtk.Clipboard().wait_for_text() or gtk.Clipboard(selection="PRIMARY").wait_for_text() if text: self.do_insert_text(text) return return def do_delete(self, *args): '''删除选中内容 ''' #print 'WebKitEdit.do_delete:' self.execute_script(' document.execCommand("delete", false, false); ') def do_selectall(self, *args): '''全选 ''' #print 'WebKitEdit.do_selectall:' self.execute_script(' document.execCommand("selectall", false, false); ') ################################################ # def do_view_update_contents(self, *args): '''更新文档目录 依据标题样式 ''' #print 'WebKitEdit.view_update_contents:' return self.eval(r''' updatedir(); ''') pass def do_view_toggle_autonumber(self, *args): '''切换标题自动编号 ''' #print 'WebKitEdit.view_toggle_autonumber:' return self.eval(r''' toggledirnu(); ''') pass def do_view_sourceview(self, *args): '''查看源码 ''' #print 'WebKitEdit.view_sourceview:' self.toggle_html_view() pass def do_insertimage(self, img=""): '''插入图片 ''' #if img.startswith('/'): img = 'file://' + img #print 'WebKitEdit.do_insertimage:', img self.execute_script(''' document.execCommand("insertimage", false, "%s"); '''%stastr(img)) pass def do_createlink(self, link=""): '''创建超链接 ''' #print 'WebKitEdit.do_createlink:' self.execute_script(r''' link = "%s"; if( !document.execCommand("createlink", false, link) ) { text = link; i = document.createElement("div"); i.textContent = text; text = i.innerHTML; html = '' + text + ''; document.execCommand("inserthtml", false, html); } '''%stastr(link)) pass def do_inserthorizontalrule(self, *args): '''插入水平线 ''' #print 'WebKitEdit.do_inserthorizontalrule:' self.execute_script(''' document.execCommand("inserthorizontalrule", false, false); ''') pass def do_insert_table(self, rows, cows): '''插入表格 会询问行、列数 ''' #print 'WebKitEdit.do_insert_table:' html = "\n\n" for row in range(int(rows)): html+= "\n" for cow in range(int(cows)): html+= " \n" html+= "\n" html+= "

\n
\n" self.do_insert_html(html) pass def do_insert_html(self, html): '''插入 html ''' #print 'WebKitEdit.do_insert_html:' if not self.get_view_source_mode(): self.execute_script(''' window.focus(); document.execCommand("inserthtml", false, "%s"); '''%stastr(html)) pass else: self.execute_script(''' var text = "%s"; var i = document.createElement("div"); i.textContent = text; html = i.innerHTML; html = html.replace(/\\ \\ /g, '  '); document.execCommand("inserthtml", false, html); '''%stastr(html)) pass pass def do_insert_text(self, text): '''插入纯文本 会先专为 html 再 insert_htm ''' #print 'WebKitEdit.do_insert_text:' self.execute_script(''' var text = "%s"; var i = document.createElement("div"); i.textContent = text; html = i.innerHTML; html = html.replace(/\\ \\ /g, '  '); html = html.replace(/\\n/g, '
\\n'); document.execCommand("inserthtml", false, html); '''%stastr(text)) pass def do_insert_contents(self, *args): '''插入目录 ''' #print 'WebKitEdit.do_insert_contents:' #@FIXME: 无法删除现存目录表格 self.execute_script(r''' if(t=document.getElementById("toctitle")){ document.removeChild(t); } html = '
目录

'; document.execCommand("inserthtml", false, html); updatedir(); '''.replace("目录", _("Table of contents"))) pass def do_formatblock_p(self, *args): '''段落样式 ''' #print 'WebKitEdit.do_formatblock_p:' return self.eval(''' document.execCommand("formatblock", false, "p"); updatedir(); ''') pass def do_formatblock_h1(self, *args): '''

样式 @NOTE: 将一行字设为标题后,回车出现的是
而非

。需要让他换行后使用

。考虑在下一行添加一个

''' #print 'WebKitEdit.do_formatblock_h1:' return self.eval(''' document.execCommand("formatblock", false, "h1"); updatedir(); ''') pass def do_formatblock_h2(self, *args): '''

样式 ''' #print 'WebKitEdit.do_formatblock_h2:' return self.eval(''' document.execCommand("formatblock", false, "h2"); updatedir(); ''') pass def do_formatblock_h3(self, *args): '''

样式 ''' #print 'WebKitEdit.do_formatblock_h3:' return self.eval(''' document.execCommand("formatblock", false, "h3"); updatedir(); ''') pass def do_formatblock_h4(self, *args): '''

样式 ''' #print 'WebKitEdit.do_formatblock_h4:' return self.eval(''' document.execCommand("formatblock", false, "h4"); updatedir(); ''') pass def do_formatblock_h5(self, *args): '''

样式 ''' #print 'WebKitEdit.do_formatblock_h5:' return self.eval(''' document.execCommand("formatblock", false, "h5"); updatedir(); ''') pass def do_formatblock_h6(self, *args): '''
样式 ''' #print 'WebKitEdit.do_formatblock_h6:' return self.eval(''' document.execCommand("formatblock", false, "h6"); updatedir(); ''') pass def do_insertunorderedlist(self, *args): '''圆点列表 ''' #print 'WebKitEdit.do_insertunorderedlist:' return self.eval(''' document.execCommand("insertunorderedlist", false, null); ''') pass def do_insertorderedlist(self, *args): '''数字列表 ''' #print 'WebKitEdit.do_insertorderedlist:' return self.eval(''' document.execCommand("insertorderedlist", false, null); ''') pass def do_formatblock_div(self, *args): ''' DIV 样式 ''' #print 'WebKitEdit.formatblock_addres:' return self.eval(''' document.execCommand("div", false, "address"); ''') pass def do_formatblock_address(self, *args): '''地址样式 ''' #print 'WebKitEdit.formatblock_addres:' return self.eval(''' document.execCommand("formatblock", false, "address"); ''') pass def do_formatblock_code(self, *args): ''' 样式 ''' #print 'WebKitEdit.do_formatblock_code:' #@FIXME: formatblock code 无效 return self.eval(''' document.execCommand("formatblock", false, "code"); ''') pass def do_formatblock_blockquote(self, *args): '''引用/缩进 样式 ''' #print 'WebKitEdit.do_formatblock_blockquote:' self.eval(''' document.execCommand("formatblock", false, "blockquote"); ''') pass def do_formatblock_pre(self, *args): '''预格式化样式 ''' #print 'WebKitEdit.do_do_formatblock_pre:' return self.eval(''' document.execCommand("formatblock", false, "pre"); ''') pass def do_bold(self, *args): '''粗体 ''' #print 'WebKitEdit.do_bold:' self.execute_script(''' document.execCommand("bold", false, null); ''') pass def do_underline(self, *args): '''下划线 ''' #print 'WebKitEdit.do_underline:' self.execute_script(''' document.execCommand("underline", false, null); ''') pass def do_italic(self, *args): '''斜体 ''' #print 'WebKitEdit.do_italic:' self.execute_script(''' document.execCommand("italic", false, null); ''') pass def do_strikethrough(self, *args): '''删除线 ''' #print 'WebKitEdit.do_strikethrough:' self.execute_script(''' document.execCommand("strikethrough", false, null); ''') pass def do_font_fontname(self, fontname): '''设置字体名称 ''' #print 'WebKitEdit.do_font_fontname:' self.execute_script(r''' document.execCommand("useCSS", false, true); document.execCommand("fontname", false, "%s"); '''%fontname) pass def do_fontsize(self, fontsize): '''设置字号 ''' #print 'WebKitEdit.do_fontsize:' self.execute_script(r''' document.execCommand("fontsize", false, "%s"); '''%fontsize) pass def do_fontsize_1(self, *args): '''设置字号 1 ''' #print 'WebKitEdit.do_fontsize_1:' self.do_fontsize(1) pass def do_fontsize_2(self, *args): '''设置字号 2 ''' #print 'WebKitEdit.do_fontsize_2:' self.do_fontsize(2) pass def do_fontsize_3(self, *args): '''设置字号 3 ''' #print 'WebKitEdit.do_fontsize_3:' self.do_fontsize(3) pass def do_fontsize_4(self, *args): '''设置字号 4 ''' #print 'WebKitEdit.do_fontsize_4:' self.do_fontsize(4) pass def do_fontsize_5(self, *args): '''设置字号 5 ''' #print 'WebKitEdit.do_fontsize_5:' self.do_fontsize(5) pass def do_fontsize_6(self, *args): '''设置字号 6 ''' #print 'WebKitEdit.do_fontsize_6:' self.do_fontsize(6) pass def do_fontsize_7(self, *args): '''设置字号 7 ''' #print 'WebKitEdit.do_fontsize_7:' self.do_fontsize(7) pass def do_color_forecolor(self, color): '''设置字体颜色 ''' #print 'WebKitEdit.do_color_forecolor:' self.execute_script(r''' document.execCommand("useCSS",false, false); document.execCommand("foreColor", false, "%s"); document.execCommand("useCSS",false, true); '''%color) pass def do_color_hilitecolor(self, color): '''设置高亮颜色 即字体背景色 ''' # 设背景色无效 需要 useCSS 选项 #print 'WebKitEdit.do_color_hilitecolor:' self.execute_script(r''' document.execCommand("useCSS",false, false); document.execCommand("hilitecolor", false, "%s"); document.execCommand("useCSS",false, true); '''%color) pass def do_removeformat(self, *args): '''清除格式 ''' #print 'WebKitEdit.do_removeformat:' self.execute_script(''' document.execCommand("removeformat", false, null); ''') pass def do_justifyleft(self, *args): '''左对齐 ''' #print 'WebKitEdit.do_justifyleft:' self.execute_script(''' document.execCommand("justifyleft", false, null); ''') pass def do_justifycenter(self, *args): '''居中 ''' #print 'WebKitEdit.do_justifycenter:' self.execute_script(''' document.execCommand("justifycenter", false, null); ''') pass def do_justifyfull(self, *args): '''分散对齐 ''' #print 'WebKitEdit.do_justifycenter:' self.execute_script(''' document.execCommand("justifyfull", false, null); ''') pass def do_justifyright(self, *args): '''右对齐 ''' #print 'WebKitEdit.do_justifyright:' self.execute_script(''' document.execCommand("justifyright", false, null); ''') pass def do_indent(self, *args): '''增大缩进 ''' #print 'WebKitEdit.do_indent:' self.execute_script(''' document.execCommand("indent", false, null); ''') pass def do_outdent(self, *args): '''减小缩进 ''' #print 'WebKitEdit.do_outdent:' self.execute_script(''' document.execCommand("outdent", false, null); ''') pass def do_subscript(self, *args): '''下标 ''' #print 'WebKitEdit.do_subscript:' self.execute_script(''' document.execCommand("subscript", false, null); ''') pass def do_superscript(self, *args): '''上标 ''' #print 'WebKitEdit.do_subperscript:' self.execute_script(''' document.execCommand("superscript", false, null); ''') pass ## def do_find_text(self, findtext): '''查找文字 ''' self.search_text(findtext, case_sensitive=0, forward=1, wrap=1) pass def do_find_text_backward(self, findtext): '''向上查找文字 ''' #print 'WebKitEdit.do_find_text_forward:', findtext, self.search_text(findtext, case_sensitive=0, forward=0, wrap=1) pass def do_replace_text(self, findtext, replacetext): '''查找替换文字 ''' #print 'WebKitEdit.do_replace_text:' if self.eval("document.getSelection().toString();"): self.do_insert_text(replacetext) return elif self.search_text(findtext, case_sensitive=0, forward=1, wrap=1): self.do_insert_text(replacetext) pass pass def do_replace_text_all(self, findtext, replacetext): '''全部替换 ''' #print 'WebKitEdit.do_replace_text_all' # ## 来到页首 while self.search_text(findtext, case_sensitive=0, forward=0, wrap=0): self.do_insert_text(replacetext) pass ## 向下搜索并替换 while self.search_text(findtext, case_sensitive=0, forward=1, wrap=0): self.do_insert_text(replacetext) pass return if __name__=="__main__": #print 'WebKitEdit.main' w=gtk.Window() w.connect("delete_event", gtk.main_quit) m=WebKitEdit() w.add(m) w.show_all() gtk.main() gwrite-0.5.1/gwrite/webkitlinkview.py0000644000175000017500000000425711534726454016432 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- '''WebkitLinkView @author: U{Jiahua Huang } @license: LGPLv3+ ''' import gobject import gtk import webkit import re def proc(html): """处理 html 链接 >>> proc(' 3.2.1 heading') ' 3.2.1 heading' """ return re.sub('( *)(.*?)(>)(.*)', '''\\2 onDblClick="window.location.href='+'+this.href;" onMouseOver="document.title=this.href;" \\3\\1\\4''', html) def stastr(stri): '''处理字符串的 ' " ''' return stri.replace("\\","\\\\").replace(r'"',r'\"').replace(r"'",r"\'").replace('\n',r'\n') class LinkTextView(webkit.WebView): #__gtype_name__ = 'LinkTextView' __gsignals__ = { 'url-clicked': (gobject.SIGNAL_RUN_LAST, None, (str, str)), # href, type } def __init__(self): webkit.WebView.__init__(self) self.connect("navigation-requested", self.on_navigation_requested) #self.connect_after("populate-popup", lambda view, menu: menu.destroy()) # 暂时禁止右键菜单 self.set_property('can-focus', False) pass def updatehtmllinks(self, html): self.load_html_string(''' %s ''' % proc(html), '') # 首次执行时还没 document.body 对象 self.updatehtmllinks = lambda html : self.execute_script('document.body.innerHTML="%s";' % stastr(proc(html))) # 保持滚动条位置 pass def on_navigation_requested(self, widget, WebKitWebFrame, WebKitNetworkRequest): href = WebKitNetworkRequest.get_uri() if '#' in href: self.emit("url-clicked", href, "link") pass return True if __name__=="__main__": main() gwrite-0.5.1/install0000755000175000017500000000030211534726454013100 0ustar aronaron#!/bin/bash -x python setup.py build_i18n -m python setup.py build [ -a /usr/bin/dpkg ] && INSTALL_LAYOUT='--install-layout deb' sudo python setup.py install $INSTALL_LAYOUT --record record.log gwrite-0.5.1/po/0000755000175000017500000000000011534726454012127 5ustar aronarongwrite-0.5.1/po/POTFILES.in0000644000175000017500000000023111534726454013700 0ustar aronarongwrite/gwrite.py gwrite/i18n.py gwrite/webkitlinkview.py gwrite/gtkdialogs.py gwrite/webkitedit.py gwrite.desktop.in gwrite/config.py gwrite/gtklatex.py gwrite-0.5.1/po/fr.po0000644000175000017500000003102711534726454013101 0ustar aronaron# French translations for gwrite package. # Copyright (C) 2010 Free Software Foundation, Inc. # This file is distributed under the same license as the gwrite package. # Ludovic Troisi , 2010. # #: ../gwrite/i18n.py:19 msgid "" msgstr "" "Project-Id-Version: GWrite\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-01-21 13:15+0800\n" "PO-Revision-Date: 2010-09-19 16:08+0100\n" "Last-Translator: Ludovic Troisi \n" "Language-Team: none\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: ../gwrite/gwrite.py:25 msgid "NewDocument" msgstr "Nouveau Document" #: ../gwrite/gwrite.py:44 ../gwrite/gwrite.py:2259 ../gwrite/gwrite.py:2260 msgid "GWrite" msgstr "GWrite" #: ../gwrite/gwrite.py:96 msgid "_File" msgstr "_Fichier" #: ../gwrite/gwrite.py:111 msgid "New _Window" msgstr "_Nouvelle Fenêtre" #: ../gwrite/gwrite.py:171 msgid "_Recently" msgstr "Documents _Récents" #: ../gwrite/gwrite.py:191 msgid "Close Win_dow" msgstr "_Fermer la Fenêtre" #: ../gwrite/gwrite.py:213 msgid "_Edit" msgstr "_Editer" #: ../gwrite/gwrite.py:254 ../gwrite/webkitedit.py:357 msgid "Pa_ste Unformatted" msgstr "Coller sans Mise en Forme" #: ../gwrite/gwrite.py:311 msgid "_View" msgstr "_Affichage" #. # 更新目录 #: ../gwrite/gwrite.py:346 ../gwrite/gwrite.py:1562 msgid "Update _Contents" msgstr "Mettre à jour le _contenu" #: ../gwrite/gwrite.py:354 ../gwrite/gwrite.py:1570 msgid "Toggle _Numbered Title" msgstr "Classer les _Titres" #: ../gwrite/gwrite.py:362 msgid "Update _Images" msgstr "Mettre à jour les _images" #: ../gwrite/gwrite.py:375 msgid "So_urce/Visual" msgstr "So_urce/Visuel" #: ../gwrite/gwrite.py:388 msgid "_Insert" msgstr "_Insérer" #: ../gwrite/gwrite.py:394 msgid "_Picture" msgstr "_Image" #: ../gwrite/gwrite.py:402 msgid "_Link" msgstr "_Lien" #: ../gwrite/gwrite.py:410 msgid "Horizontal_Rule" msgstr "Ligne _Horizontale" #: ../gwrite/gwrite.py:418 msgid "_Table" msgstr "_Tableau" #: ../gwrite/gwrite.py:426 msgid "_HTML" msgstr "_Code HTML" #. # #: ../gwrite/gwrite.py:440 msgid "LaTeX _Equation" msgstr "_Equation LaTex" #. # #: ../gwrite/gwrite.py:449 msgid "_Contents" msgstr "Table des _Matières" #: ../gwrite/gwrite.py:461 msgid "_Style" msgstr "_Style" #: ../gwrite/gwrite.py:467 msgid "_Normal" msgstr "_Normal" #: ../gwrite/gwrite.py:480 msgid "Heading _1" msgstr "Titre _1" #: ../gwrite/gwrite.py:488 msgid "Heading _2" msgstr "Titre _2" #: ../gwrite/gwrite.py:496 msgid "Heading _3" msgstr "Titre _3" #: ../gwrite/gwrite.py:504 ../gwrite/gwrite.py:970 msgid "Heading _4" msgstr "Titre _4" #: ../gwrite/gwrite.py:512 ../gwrite/gwrite.py:978 msgid "Heading _5" msgstr "Titre _5" #: ../gwrite/gwrite.py:520 ../gwrite/gwrite.py:986 msgid "Heading _6" msgstr "Titre _6" #: ../gwrite/gwrite.py:533 ../gwrite/gwrite.py:999 msgid "_Bulleted List" msgstr "Liste à _puces" #: ../gwrite/gwrite.py:541 ../gwrite/gwrite.py:1007 msgid "Numbered _List" msgstr "Liste _Numérotée" #: ../gwrite/gwrite.py:554 ../gwrite/gwrite.py:1020 msgid "Di_v" msgstr "Di_v" #: ../gwrite/gwrite.py:562 ../gwrite/gwrite.py:1028 msgid "A_ddress" msgstr "A_dresse" #. menuitem_formatblock_code = gtk.ImageMenuItem(_("_Code")) #. menuitem_formatblock_code.show() #. menuitem_formatblock_code.connect("activate", self.do_formatblock_code) #. #. img = gtk.image_new_from_icon_name('stock_text-monospaced', gtk.ICON_SIZE_MENU) #. menuitem_formatblock_code.set_image(img) #. menu_style.append(menuitem_formatblock_code) #: ../gwrite/gwrite.py:578 ../gwrite/gwrite.py:1044 msgid "Block_quote" msgstr "Ci_tation" #: ../gwrite/gwrite.py:586 ../gwrite/gwrite.py:1052 msgid "_Preformat" msgstr "_Preformat" #: ../gwrite/gwrite.py:598 msgid "For_mat" msgstr "_Mise en Forme" #: ../gwrite/gwrite.py:669 msgid "Font _Size" msgstr "Taille de la _Police" #: ../gwrite/gwrite.py:677 msgid "_1" msgstr "_1" #: ../gwrite/gwrite.py:683 msgid "_2" msgstr "_2" #: ../gwrite/gwrite.py:689 msgid "_3" msgstr "_3" #: ../gwrite/gwrite.py:695 msgid "_4" msgstr "_4" #: ../gwrite/gwrite.py:701 msgid "_5" msgstr "_5" #: ../gwrite/gwrite.py:707 msgid "_6" msgstr "_6" #: ../gwrite/gwrite.py:713 msgid "_7" msgstr "_7" #: ../gwrite/gwrite.py:729 msgid "_Highlight" msgstr "_Surligner" #: ../gwrite/gwrite.py:738 msgid "_HiliteColor" msgstr "_Couleur de Surlignage" #: ../gwrite/gwrite.py:746 msgid "_Clear format" msgstr "_Effacer la Mise en Forme" #: ../gwrite/gwrite.py:799 msgid "Subs_cript" msgstr "I_ndice" #: ../gwrite/gwrite.py:807 msgid "Su_perscript" msgstr "E_xposant" #. # #: ../gwrite/gwrite.py:819 msgid "_Tools" msgstr "_Outils" #: ../gwrite/gwrite.py:825 msgid "_Word Count" msgstr "Total des _Mots" #. # #: ../gwrite/gwrite.py:837 msgid "_Help" msgstr "_Aide" #: ../gwrite/gwrite.py:864 msgid "New" msgstr "Nouveau" #. -print 'on_open:' #: ../gwrite/gwrite.py:871 ../gwrite/gwrite.py:1750 #: ../gwrite/gtkdialogs.py:374 msgid "Open" msgstr "Ouvrir" #: ../gwrite/gwrite.py:879 ../gwrite/gwrite.py:1770 #: ../gwrite/gtkdialogs.py:437 msgid "Save" msgstr "Enregistrer" #: ../gwrite/gwrite.py:890 msgid "Undo" msgstr "Annuler" #: ../gwrite/gwrite.py:897 msgid "Redo" msgstr "Réitérer" #: ../gwrite/gwrite.py:908 msgid "Cut" msgstr "Couper" #: ../gwrite/gwrite.py:915 msgid "Copy" msgstr "Copier" #: ../gwrite/gwrite.py:922 msgid "Paste" msgstr "Coller" #: ../gwrite/gwrite.py:935 ../gwrite/gwrite.py:936 msgid "Paragraph" msgstr "Paragraphe" #: ../gwrite/gwrite.py:943 ../gwrite/gwrite.py:944 msgid "Heading 1" msgstr "Titre 1" #: ../gwrite/gwrite.py:951 ../gwrite/gwrite.py:952 msgid "Heading 2" msgstr "Titre 2" #: ../gwrite/gwrite.py:961 ../gwrite/gwrite.py:962 msgid "Heading 3" msgstr "Titre 3" #: ../gwrite/gwrite.py:963 msgid "Style" msgstr "Style" #: ../gwrite/gwrite.py:1091 ../gwrite/gwrite.py:1092 msgid "Bold" msgstr "Gras" #: ../gwrite/gwrite.py:1102 ../gwrite/gwrite.py:1103 msgid "Highlight" msgstr "Surligner" #: ../gwrite/gwrite.py:1104 msgid "Select hilitecolor" msgstr "Choisir la Couleur de Surlignage" #: ../gwrite/gwrite.py:1117 ../gwrite/gwrite.py:1118 msgid "Clear format" msgstr "Effacer la Mise en Forme" #: ../gwrite/gwrite.py:1186 msgid "Close Findbar" msgstr "Fermer la Barre de recherche" #: ../gwrite/gwrite.py:1206 ../gwrite/gwrite.py:1231 msgid "Find Next" msgstr "Chercher le suivant" #: ../gwrite/gwrite.py:1208 ../gwrite/gwrite.py:2290 msgid "Search text" msgstr "Chercher le texte" #: ../gwrite/gwrite.py:1214 msgid "Find Previous" msgstr "Chercher le précédent" #: ../gwrite/gwrite.py:1226 msgid "Find" msgstr "Chercher" #: ../gwrite/gwrite.py:1243 msgid "Replace text" msgstr "Remplacer le texte" #: ../gwrite/gwrite.py:1245 ../gwrite/gwrite.py:1249 ../gwrite/gwrite.py:1266 #: ../gwrite/gtkdialogs.py:498 msgid "Replace" msgstr "Remplacer" #: ../gwrite/gwrite.py:1279 msgid "Replace All" msgstr "Tout remplacer" #: ../gwrite/gwrite.py:1280 msgid "ReplaceAll" msgstr "Tout remplacer" #: ../gwrite/gwrite.py:1448 msgid "Navigation Pane" msgstr "Panneau de navigation" #: ../gwrite/gwrite.py:1499 #, python-format msgid "[New Document] %s" msgstr "[Nouveau Document] %s" #: ../gwrite/gwrite.py:1503 msgid "[New Document]" msgstr "[Nouveau Document]" #: ../gwrite/gwrite.py:1550 msgid "_Select this" msgstr "_Sélectionner" #: ../gwrite/gwrite.py:1553 msgid "您也可以直接双击以选择该章节文字" msgstr "您也可以直接双击以选择该章节文字" #. # r: 1, -1, 0 => yes, no, cancel #: ../gwrite/gwrite.py:1632 #, python-format msgid "%s Save Changes?" msgstr "%s Enregistrer les Changements?" #: ../gwrite/gwrite.py:1752 ../gwrite/gwrite.py:1771 ../gwrite/gwrite.py:1802 msgid "Html Document" msgstr "Document HTML" #: ../gwrite/gwrite.py:1753 msgid "MS Doc Document" msgstr "Document MS Doc" #: ../gwrite/gwrite.py:1780 ../gwrite/gwrite.py:1811 msgid "Unable to write to file." msgstr "Incapable d'écrire le fichier" #: ../gwrite/gwrite.py:1801 msgid "Save As" msgstr "Enregistrer Sous" #: ../gwrite/gwrite.py:1847 msgid "Document" msgstr "Document" #: ../gwrite/gwrite.py:1847 msgid "Selection" msgstr "Sélection" #: ../gwrite/gwrite.py:1848 msgid "Words: " msgstr "Mots:" #: ../gwrite/gwrite.py:1849 msgid "Characters (with spaces): " msgstr "Caractères (avec espaces):" #: ../gwrite/gwrite.py:1850 msgid "Characters (no spaces): " msgstr "Caractères (sans espaces):" #: ../gwrite/gwrite.py:1851 msgid "Paragraphs: " msgstr "Paragraphes: " #: ../gwrite/gwrite.py:1852 msgid "Lines: " msgstr "Lignes:" #: ../gwrite/gwrite.py:1853 msgid "English words: " msgstr "Mots en Anglais:" #: ../gwrite/gwrite.py:1854 msgid "Chinese characters: " msgstr "Caractères Chinois:" #. -print info #: ../gwrite/gwrite.py:1857 msgid "Word Counts" msgstr "Total des Mots" #. -print 'do_insertimage:' #: ../gwrite/gwrite.py:1957 msgid "InsertImage" msgstr "Insérer une Image" #: ../gwrite/gwrite.py:1957 msgid "Image Files" msgstr "Fichiers Image" #. -print 'do_createlink:' #. #print self.edit.get_link_message() #: ../gwrite/gwrite.py:1965 msgid "Create Link" msgstr "Créer un Lien" #: ../gwrite/gwrite.py:1965 msgid "URL:" msgstr "Adresse Internet:" #. -print 'do_insert_table:' #: ../gwrite/gwrite.py:1978 msgid "Insert Table" msgstr "Insérer un Tableau" #: ../gwrite/gwrite.py:1978 msgid "Rows:" msgstr "Lignes:" #: ../gwrite/gwrite.py:1978 msgid "Cows:" msgstr "Colonnes:" #. -print 'do_insert_html:' #: ../gwrite/gwrite.py:1984 msgid "Insert Html" msgstr "Insérer le code HTML" #: ../gwrite/gwrite.py:2263 msgid "Copyright (C) 2009-2010 Jiahua Huang, Aron Xu" msgstr "Copyright (C) 2009-2010 Jiahua Huang, Aron Xu" #: ../gwrite/gwrite.py:2264 msgid "Simple GTK+ HTML5 Rich Text Editor" msgstr "Simple Éditeur de texte et HTML5 en GTK+" #: ../gwrite/gwrite.py:2285 #, python-format msgid "%s matches" msgstr "%s correspond" #: ../gwrite/gwrite.py:2328 #, python-format msgid "(custom widget: %s)" msgstr "(widget personnalisé: %s)" #. #cmd test #: ../gwrite/gwrite.py:2334 msgid "" "GWrite\n" "\n" "Usage:\n" " gwrite [OPTION...] [FILE...] - Edit html files\n" "\n" "Options:\n" " -h, --help Show help options\n" " -v, --version Show version information\n" msgstr "" "GWrite\n" "\n" "Utilisation:\n" " gwrite [OPTION...] [FILE...] - Editer les fichiers html\n" "\n" "Options:\n" " -h, --help Montrer les Options de l'aide\n" " -v, --version Montrer la version\n" #: ../gwrite/gtkdialogs.py:263 msgid "Save Changes?" msgstr "Enregistrer les Changements ?" #: ../gwrite/gtkdialogs.py:276 msgid "Info" msgstr "Info" #: ../gwrite/gtkdialogs.py:276 msgid "Key:" msgstr "Clé:" #: ../gwrite/gtkdialogs.py:276 msgid "Value" msgstr "Valeur" #: ../gwrite/gtkdialogs.py:334 msgid "Click here for details" msgstr "Cliquez ici pour plus de détails" #: ../gwrite/gtkdialogs.py:399 ../gwrite/gtkdialogs.py:462 msgid "All Files" msgstr "Tous les Fichiers" #: ../gwrite/gtkdialogs.py:424 #, python-format msgid "Could not open file \"%s\"" msgstr "Impossible d'ouvrir le fichier \"%s\"" #: ../gwrite/gtkdialogs.py:425 #, python-format msgid "The file \"%s\" could not be opened. Permission denied." msgstr "Le fichier \"%s\" n'a pa pu être ouvert. Permission refusée." #: ../gwrite/gtkdialogs.py:488 #, python-format msgid "A file named \"%s\" already exists" msgstr "Un fichier dénommé \"%s\" existe déjà" #: ../gwrite/gtkdialogs.py:489 msgid "Do you which to replace it with the current project?" msgstr "Désirez-vous le remplacer avec le projet actuel ?" #. print 'WebKitEdit.do_insert_contents:' #. @FIXME: 无法删除现存目录表格 #: ../gwrite/webkitedit.py:945 msgid "Table of contents" msgstr "Table des matières" #: ../gwrite/config.py:65 msgid "Preferences" msgstr "Préférences" #: ../gwrite/config.py:86 msgid "Use Tabs MDI interface" msgstr "Interface MDI" #: ../gwrite/config.py:87 msgid "" "Supports editing multiple files in one window (known sometimes as tabs or " "MDI)" msgstr "" "Permet d'éditer plusieurs fichiers sur une seule fenêtre (Multi Documents " "Interface)" #: ../gwrite/config.py:96 msgid "Single Instance mode" msgstr "Mode Une seule Instance" #: ../gwrite/config.py:97 msgid "Only one instance of the application will be running at a time." msgstr "Une seule instance de l'application peut être utilisée à la fois." #: ../gwrite/config.py:108 msgid "You need to restart gwrite for some options to take effect." msgstr "Vous devez redémarrer GWrite pour appliquer les changements." #: ../gwrite/config.py:117 msgid "Run mode" msgstr "Options d'utilisation" #: ../gwrite/gtklatex.py:344 msgid "LaTeX math expressions" msgstr "Expressions mathématiques LaTex" gwrite-0.5.1/po/zh_CN.po0000644000175000017500000003032711534726454013475 0ustar aronaron# Simplified Chinese translation for GWrite. # Copyright (C) Jiahua Huang, 2009, 2010 # Copyright (C) Aron Xu, 2010 # This file is distributed under the same license as the GWrite package. # Jiahua Huang , 2009, 2010. # Aron Xu , 2010. # #: ../gwrite/i18n.py:19 msgid "" msgstr "" "Project-Id-Version: gwrite 0.0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-01-21 13:15+0800\n" "PO-Revision-Date: 2010-01-25 18:58+0800\n" "Last-Translator: Jiahua Huang \n" "Language-Team: Chinese/Simplified\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../gwrite/gwrite.py:25 msgid "NewDocument" msgstr "新建文档" #: ../gwrite/gwrite.py:44 ../gwrite/gwrite.py:2259 ../gwrite/gwrite.py:2260 msgid "GWrite" msgstr "写字板" #: ../gwrite/gwrite.py:96 msgid "_File" msgstr "文件(_F)" #: ../gwrite/gwrite.py:111 msgid "New _Window" msgstr "新建窗口(_W)" #: ../gwrite/gwrite.py:171 msgid "_Recently" msgstr "最近的文档(_R)" #: ../gwrite/gwrite.py:191 msgid "Close Win_dow" msgstr "关闭窗口(_D)" #: ../gwrite/gwrite.py:213 msgid "_Edit" msgstr "编辑(_E)" #: ../gwrite/gwrite.py:254 ../gwrite/webkitedit.py:357 msgid "Pa_ste Unformatted" msgstr "无格式粘贴(_S)" #: ../gwrite/gwrite.py:311 msgid "_View" msgstr "查看(_V)" #. # 更新目录 #: ../gwrite/gwrite.py:346 ../gwrite/gwrite.py:1562 msgid "Update _Contents" msgstr "更新目录(_C)" #: ../gwrite/gwrite.py:354 ../gwrite/gwrite.py:1570 msgid "Toggle _Numbered Title" msgstr "切换标题自动编号(_N)" #: ../gwrite/gwrite.py:362 msgid "Update _Images" msgstr "更新图片(_I)" #: ../gwrite/gwrite.py:375 msgid "So_urce/Visual" msgstr "源码/可视化(_U)" #: ../gwrite/gwrite.py:388 msgid "_Insert" msgstr "插入(_I)" #: ../gwrite/gwrite.py:394 msgid "_Picture" msgstr "图片(_P)" #: ../gwrite/gwrite.py:402 msgid "_Link" msgstr "链接(_L)" #: ../gwrite/gwrite.py:410 msgid "Horizontal_Rule" msgstr "水平线(_R)" #: ../gwrite/gwrite.py:418 msgid "_Table" msgstr "表格(_T)" #: ../gwrite/gwrite.py:426 msgid "_HTML" msgstr "_HTML" #. # #: ../gwrite/gwrite.py:440 msgid "LaTeX _Equation" msgstr "LaTex 公式(_E)" #. # #: ../gwrite/gwrite.py:449 msgid "_Contents" msgstr "目录(_C)" #: ../gwrite/gwrite.py:461 msgid "_Style" msgstr "样式(_S)" #: ../gwrite/gwrite.py:467 msgid "_Normal" msgstr "段落(_N)" #: ../gwrite/gwrite.py:480 msgid "Heading _1" msgstr "标题 _1" #: ../gwrite/gwrite.py:488 msgid "Heading _2" msgstr "标题 _2" #: ../gwrite/gwrite.py:496 msgid "Heading _3" msgstr "标题 _3" #: ../gwrite/gwrite.py:504 ../gwrite/gwrite.py:970 msgid "Heading _4" msgstr "标题 _4" #: ../gwrite/gwrite.py:512 ../gwrite/gwrite.py:978 msgid "Heading _5" msgstr "标题 _5" #: ../gwrite/gwrite.py:520 ../gwrite/gwrite.py:986 msgid "Heading _6" msgstr "标题 _6" #: ../gwrite/gwrite.py:533 ../gwrite/gwrite.py:999 msgid "_Bulleted List" msgstr "圆点列表(_B)" #: ../gwrite/gwrite.py:541 ../gwrite/gwrite.py:1007 msgid "Numbered _List" msgstr "数字列表(_L)" #: ../gwrite/gwrite.py:554 ../gwrite/gwrite.py:1020 msgid "Di_v" msgstr "DIV 块(_V)" #: ../gwrite/gwrite.py:562 ../gwrite/gwrite.py:1028 msgid "A_ddress" msgstr "地址(_D)" #. menuitem_formatblock_code = gtk.ImageMenuItem(_("_Code")) #. menuitem_formatblock_code.show() #. menuitem_formatblock_code.connect("activate", self.do_formatblock_code) #. #. img = gtk.image_new_from_icon_name('stock_text-monospaced', gtk.ICON_SIZE_MENU) #. menuitem_formatblock_code.set_image(img) #. menu_style.append(menuitem_formatblock_code) #: ../gwrite/gwrite.py:578 ../gwrite/gwrite.py:1044 msgid "Block_quote" msgstr "引用(_Q)" #: ../gwrite/gwrite.py:586 ../gwrite/gwrite.py:1052 msgid "_Preformat" msgstr "预格式化(_P)" #: ../gwrite/gwrite.py:598 msgid "For_mat" msgstr "格式(_M)" #: ../gwrite/gwrite.py:669 msgid "Font _Size" msgstr "字号(_S)" #: ../gwrite/gwrite.py:677 msgid "_1" msgstr "_1" #: ../gwrite/gwrite.py:683 msgid "_2" msgstr "_2" #: ../gwrite/gwrite.py:689 msgid "_3" msgstr "_3" #: ../gwrite/gwrite.py:695 msgid "_4" msgstr "_4" #: ../gwrite/gwrite.py:701 msgid "_5" msgstr "_5" #: ../gwrite/gwrite.py:707 msgid "_6" msgstr "_6" #: ../gwrite/gwrite.py:713 msgid "_7" msgstr "_7" #: ../gwrite/gwrite.py:729 msgid "_Highlight" msgstr "高亮(_H)" #: ../gwrite/gwrite.py:738 msgid "_HiliteColor" msgstr "选择高亮颜色(_H)" #: ../gwrite/gwrite.py:746 msgid "_Clear format" msgstr "清除格式(_C)" #: ../gwrite/gwrite.py:799 msgid "Subs_cript" msgstr "下标(_C)" #: ../gwrite/gwrite.py:807 msgid "Su_perscript" msgstr "上标(_P)" #. # #: ../gwrite/gwrite.py:819 msgid "_Tools" msgstr "工具(_T)" #: ../gwrite/gwrite.py:825 msgid "_Word Count" msgstr "字数统计(_W)" #. # #: ../gwrite/gwrite.py:837 msgid "_Help" msgstr "帮助(_H)" #: ../gwrite/gwrite.py:864 msgid "New" msgstr "新建" #. -print 'on_open:' #: ../gwrite/gwrite.py:871 ../gwrite/gwrite.py:1750 #: ../gwrite/gtkdialogs.py:374 msgid "Open" msgstr "打开" #: ../gwrite/gwrite.py:879 ../gwrite/gwrite.py:1770 #: ../gwrite/gtkdialogs.py:437 msgid "Save" msgstr "保存" #: ../gwrite/gwrite.py:890 msgid "Undo" msgstr "撤销" #: ../gwrite/gwrite.py:897 msgid "Redo" msgstr "重做" #: ../gwrite/gwrite.py:908 msgid "Cut" msgstr "剪切" #: ../gwrite/gwrite.py:915 msgid "Copy" msgstr "复制" #: ../gwrite/gwrite.py:922 msgid "Paste" msgstr "粘贴" #: ../gwrite/gwrite.py:935 ../gwrite/gwrite.py:936 msgid "Paragraph" msgstr "段落" #: ../gwrite/gwrite.py:943 ../gwrite/gwrite.py:944 msgid "Heading 1" msgstr "标题一" #: ../gwrite/gwrite.py:951 ../gwrite/gwrite.py:952 msgid "Heading 2" msgstr "标题二" #: ../gwrite/gwrite.py:961 ../gwrite/gwrite.py:962 msgid "Heading 3" msgstr "标题三" #: ../gwrite/gwrite.py:963 msgid "Style" msgstr "样式" #: ../gwrite/gwrite.py:1091 ../gwrite/gwrite.py:1092 msgid "Bold" msgstr "粗体" #: ../gwrite/gwrite.py:1102 ../gwrite/gwrite.py:1103 msgid "Highlight" msgstr "高亮" #: ../gwrite/gwrite.py:1104 msgid "Select hilitecolor" msgstr "选择高亮颜色" #: ../gwrite/gwrite.py:1117 ../gwrite/gwrite.py:1118 msgid "Clear format" msgstr "清除格式" #: ../gwrite/gwrite.py:1186 msgid "Close Findbar" msgstr "关闭查找栏" #: ../gwrite/gwrite.py:1206 ../gwrite/gwrite.py:1231 msgid "Find Next" msgstr "查找下一个" #: ../gwrite/gwrite.py:1208 ../gwrite/gwrite.py:2290 msgid "Search text" msgstr "查找文字" #: ../gwrite/gwrite.py:1214 msgid "Find Previous" msgstr "查找上一个" #: ../gwrite/gwrite.py:1226 msgid "Find" msgstr "查找" #: ../gwrite/gwrite.py:1243 msgid "Replace text" msgstr "替换为" #: ../gwrite/gwrite.py:1245 ../gwrite/gwrite.py:1249 ../gwrite/gwrite.py:1266 #: ../gwrite/gtkdialogs.py:498 msgid "Replace" msgstr "替换" #: ../gwrite/gwrite.py:1279 msgid "Replace All" msgstr "全部替换" #: ../gwrite/gwrite.py:1280 msgid "ReplaceAll" msgstr "全部替换" #: ../gwrite/gwrite.py:1448 msgid "Navigation Pane" msgstr "导航栏" #: ../gwrite/gwrite.py:1499 #, python-format msgid "[New Document] %s" msgstr "[ 新建文档 ] %s" #: ../gwrite/gwrite.py:1503 msgid "[New Document]" msgstr "新建文档" #: ../gwrite/gwrite.py:1550 msgid "_Select this" msgstr "选择该章节(_S)" #: ../gwrite/gwrite.py:1553 msgid "您也可以直接双击以选择该章节文字" msgstr "您也可以直接双击以选择该章节文字" #. # r: 1, -1, 0 => yes, no, cancel #: ../gwrite/gwrite.py:1632 #, python-format msgid "%s Save Changes?" msgstr "%s 是否保存修改?" #: ../gwrite/gwrite.py:1752 ../gwrite/gwrite.py:1771 ../gwrite/gwrite.py:1802 msgid "Html Document" msgstr "HTML 文档" #: ../gwrite/gwrite.py:1753 msgid "MS Doc Document" msgstr "Doc 文档" #: ../gwrite/gwrite.py:1780 ../gwrite/gwrite.py:1811 msgid "Unable to write to file." msgstr "无法写入文件。" #: ../gwrite/gwrite.py:1801 msgid "Save As" msgstr "另存为" #: ../gwrite/gwrite.py:1847 msgid "Document" msgstr "文档" #: ../gwrite/gwrite.py:1847 msgid "Selection" msgstr "选中范围" #: ../gwrite/gwrite.py:1848 msgid "Words: " msgstr "字数: " #: ../gwrite/gwrite.py:1849 msgid "Characters (with spaces): " msgstr "字符数(算空格): " #: ../gwrite/gwrite.py:1850 msgid "Characters (no spaces): " msgstr "字符数(无空格): " #: ../gwrite/gwrite.py:1851 msgid "Paragraphs: " msgstr "段落: " #: ../gwrite/gwrite.py:1852 msgid "Lines: " msgstr "行数: " #: ../gwrite/gwrite.py:1853 msgid "English words: " msgstr "单词: " #: ../gwrite/gwrite.py:1854 msgid "Chinese characters: " msgstr "中文字: " #. -print info #: ../gwrite/gwrite.py:1857 msgid "Word Counts" msgstr "字数统计" #. -print 'do_insertimage:' #: ../gwrite/gwrite.py:1957 msgid "InsertImage" msgstr "插入图片" #: ../gwrite/gwrite.py:1957 msgid "Image Files" msgstr "图片文件" #. -print 'do_createlink:' #. #print self.edit.get_link_message() #: ../gwrite/gwrite.py:1965 msgid "Create Link" msgstr "创建链接" #: ../gwrite/gwrite.py:1965 msgid "URL:" msgstr "URL:" #. -print 'do_insert_table:' #: ../gwrite/gwrite.py:1978 msgid "Insert Table" msgstr "插入表格" #: ../gwrite/gwrite.py:1978 msgid "Rows:" msgstr "行数:" #: ../gwrite/gwrite.py:1978 msgid "Cows:" msgstr "列数:" #. -print 'do_insert_html:' #: ../gwrite/gwrite.py:1984 msgid "Insert Html" msgstr "插入 HTML" #: ../gwrite/gwrite.py:2263 msgid "Copyright (C) 2009-2010 Jiahua Huang, Aron Xu" msgstr "版权所有 (C) 2009-2010 Jiahua Huang, Aron Xu" #: ../gwrite/gwrite.py:2264 msgid "Simple GTK+ HTML5 Rich Text Editor" msgstr "简易的 GTK+ HTML5 写字板" #: ../gwrite/gwrite.py:2285 #, python-format msgid "%s matches" msgstr "%s 个匹配" #: ../gwrite/gwrite.py:2328 #, python-format msgid "(custom widget: %s)" msgstr "(自定义控件: %s)" #. #cmd test #: ../gwrite/gwrite.py:2334 msgid "" "GWrite\n" "\n" "Usage:\n" " gwrite [OPTION...] [FILE...] - Edit html files\n" "\n" "Options:\n" " -h, --help Show help options\n" " -v, --version Show version information\n" msgstr "" "GWrite\n" "\n" "用法:\n" " gwrite [选项...] [文件...] - 编辑 HTML 文件\n" "\n" "选项:\n" " -h, --help\t\t\t显示帮助选项\n" " -v, --version\t\t显示版本信息\n" #: ../gwrite/gtkdialogs.py:263 msgid "Save Changes?" msgstr "是否保存修改?" #: ../gwrite/gtkdialogs.py:276 msgid "Info" msgstr "信息" #: ../gwrite/gtkdialogs.py:276 msgid "Key:" msgstr "键名:" #: ../gwrite/gtkdialogs.py:276 msgid "Value" msgstr "键值" #: ../gwrite/gtkdialogs.py:334 msgid "Click here for details" msgstr "点击查看详情" #: ../gwrite/gtkdialogs.py:399 ../gwrite/gtkdialogs.py:462 msgid "All Files" msgstr "所有文件" #: ../gwrite/gtkdialogs.py:424 #, python-format msgid "Could not open file \"%s\"" msgstr "无法打开文件 \"%s\"" #: ../gwrite/gtkdialogs.py:425 #, python-format msgid "The file \"%s\" could not be opened. Permission denied." msgstr "无法打开文件 \"%s\"。没有权限" #: ../gwrite/gtkdialogs.py:488 #, python-format msgid "A file named \"%s\" already exists" msgstr "文件 \"%s\" 已经存在" #: ../gwrite/gtkdialogs.py:489 msgid "Do you which to replace it with the current project?" msgstr "您是否想要替换它?" #. print 'WebKitEdit.do_insert_contents:' #. @FIXME: 无法删除现存目录表格 #: ../gwrite/webkitedit.py:945 msgid "Table of contents" msgstr "目录" #: ../gwrite/config.py:65 msgid "Preferences" msgstr "首选项" #: ../gwrite/config.py:86 msgid "Use Tabs MDI interface" msgstr "使用多标签页界面" #: ../gwrite/config.py:87 msgid "" "Supports editing multiple files in one window (known sometimes as tabs or " "MDI)" msgstr "支持在一个窗口里编辑多个文件(通常叫多标签页,或 MDI)" #: ../gwrite/config.py:96 msgid "Single Instance mode" msgstr "单实例模式" #: ../gwrite/config.py:97 msgid "Only one instance of the application will be running at a time." msgstr "同一时间只运行一个程序实例" #: ../gwrite/config.py:108 msgid "You need to restart gwrite for some options to take effect." msgstr "部分选项需要重启生效。" #: ../gwrite/config.py:117 msgid "Run mode" msgstr "运行模式" #: ../gwrite/gtklatex.py:344 msgid "LaTeX math expressions" msgstr "LaTex 数学公式" #~ msgid "HTML" #~ msgstr "HTML" #~ msgid "(C) hiweed.com" #~ msgstr "(C) hiweed.com" gwrite-0.5.1/scripts/0000755000175000017500000000000011534726454013200 5ustar aronarongwrite-0.5.1/scripts/gwrite0000755000175000017500000000044711534726454014434 0ustar aronaron#!/usr/bin/python # -*- coding: UTF-8 -*- # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: # Author: Huang Jiahua # License: GNU LGPL # Last modified: """ """ __revision__ = '0.1' if __name__=="__main__": import gwrite.gwrite gwrite.gwrite.main() gwrite-0.5.1/setup.cfg0000644000175000017500000000021211534726454013325 0ustar aronaron[install] prefix=/usr [build] i18n = True [build_i18n] domain = gwrite desktop_files = [('share/applications', ('gwrite.desktop.in',))] gwrite-0.5.1/setup.py0000755000175000017500000000273011534726454013230 0ustar aronaron#!/usr/bin/python from distutils.core import setup from DistUtilsExtra.command import * from glob import glob setup(name='gwrite', version='0.5.1', description='HTML5 Doc Writer based on GTK2', long_description ="""GWrite is a simple HTML5 Doc Writer base on Gtk2. Features include: 1. HTML Format 2. Indexes and Tables 3. Headings order processor 4. Hyper links 5. Images resize / scale 6. Base64 URL scheme inline images 7. Font size and styles 8. undo/redo 9. Inline pixel margin setting on paragraph / span / block attributes 10. Bullet list / Orderet list 11. Paste image direct from from other application 12. Paste html direct from firefox browser image included 13. Paste excel formated table section copy from openoffice 14. Paste full html page direct from browser image included """, author='Jiahua Huang', author_email='jhuangjiahua@gmail.com', license='LGPL-3', url="http://code.google.com/p/gwrite", download_url="http://code.google.com/p/gwrite/downloads/list", platforms = ['Linux'], scripts=['scripts/gwrite'], packages = ['gwrite'], package_data = {'gwrite': ['icons/*']}, data_files = [ ('share/pixmaps', ['gwrite.png']), ], include_data_files = [ ('.', ['po']), ], cmdclass = { "build" : build_extra.build_extra, "build_i18n" : build_i18n.build_i18n, } )