# HG changeset patch # User Rik # Date 1396637414 25200 # Node ID 37d5a2bb4160304e20446d762adc74f3caf8556b # Parent aff86394c201c71b3399df40f355c0fa8e8b81bd# Parent 359581bba58dfb013879379cde28105543446482 maint: Merge away extra head. diff -r aff86394c201 -r 37d5a2bb4160 libgui/Makefile.am --- a/libgui/Makefile.am Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/Makefile.am Fri Apr 04 11:50:14 2014 -0700 @@ -34,7 +34,8 @@ languages/pt_BR.ts \ languages/pt_PT.ts \ languages/ru_RU.ts \ - languages/uk_UA.ts + languages/uk_UA.ts \ + languages/zh_CN.ts LOCALES = $(patsubst languages/%.ts, languages/%.qm, $(TRANSLATIONS)) diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/BaseControl.cc --- a/libgui/graphics/BaseControl.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/BaseControl.cc Fri Apr 04 11:50:14 2014 -0700 @@ -195,6 +195,20 @@ } } break; + case QEvent::MouseMove: + if (qWidget ()->hasMouseTracking ()) + { + gh_manager::auto_lock lock; + + QMouseEvent* m = dynamic_cast (event); + graphics_object go = object (); + graphics_object fig = go.get_ancestor ("figure"); + + gh_manager::post_set (fig.get_handle (), "currentpoint", + Utils::figureCurrentPoint (fig, m), false); + gh_manager::post_callback (fig.get_handle (), "windowbuttonmotionfcn"); + } + break; case QEvent::KeyPress: if (m_keyPressHandlerDefined) { diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/Canvas.cc --- a/libgui/graphics/Canvas.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/Canvas.cc Fri Apr 04 11:50:14 2014 -0700 @@ -51,6 +51,41 @@ m_redrawBlocked = block; } +void Canvas::updateCurrentPoint(const graphics_object& fig, + const graphics_object& obj, QMouseEvent* event) +{ + gh_manager::post_set (fig.get_handle (), "currentpoint", + Utils::figureCurrentPoint (fig, event), false); + + Matrix children = obj.get_properties ().get_children (); + octave_idx_type num_children = children.numel (); + + for (int i = 0; i < num_children; i++) + { + graphics_object childObj (gh_manager::get_object (children(i))); + + if (childObj.isa ("axes")) + { + axes::properties& ap = Utils::properties (childObj); + Matrix x_zlim = ap.get_transform_zlim (); + graphics_xform x_form = ap.get_transform (); + + ColumnVector p1 = x_form.untransform (event->x (), event->y (), + x_zlim(0)); + ColumnVector p2 = x_form.untransform (event->x (), event->y (), + x_zlim(1)); + + Matrix cp (2, 3, 0.0); + + cp(0,0) = p1(0); cp(0,1) = p1(1); cp(0,2) = p1(2); + cp(1,0) = p2(0); cp(1,1) = p2(1); cp(1,2) = p2(2); + + gh_manager::post_set (childObj.get_handle (), "currentpoint", cp, + false); + } + } +} + void Canvas::canvasPaintEvent (void) { if (! m_redrawBlocked) @@ -134,6 +169,19 @@ break; } } + else if (m_mouseMode == NoMode) + { + graphics_object obj = gh_manager::get_object (m_handle); + + if (obj.valid_object ()) + { + graphics_object figObj (obj.get_ancestor ("figure")); + + updateCurrentPoint (figObj, obj, event); + gh_manager::post_callback (figObj.get_handle (), + "windowbuttonmotionfcn"); + } + } } void Canvas::canvasMousePressEvent (QMouseEvent* event) @@ -228,9 +276,7 @@ case NoMode: gh_manager::post_set (figObj.get_handle (), "selectiontype", Utils::figureSelectionType (event), false); - gh_manager::post_set (figObj.get_handle (), "currentpoint", - Utils::figureCurrentPoint (figObj, event), - false); + updateCurrentPoint (figObj, obj, event); gh_manager::post_callback (figObj.get_handle (), "windowbuttondownfcn"); gh_manager::post_callback (currentObj.get_handle (), @@ -321,9 +367,7 @@ { graphics_object figObj (obj.get_ancestor ("figure")); - gh_manager::post_set (figObj.get_handle (), "currentpoint", - Utils::figureCurrentPoint (figObj, event), - false); + updateCurrentPoint (figObj, obj, event); gh_manager::post_callback (figObj.get_handle (), "windowbuttonupfcn"); } diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/Canvas.h --- a/libgui/graphics/Canvas.h Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/Canvas.h Fri Apr 04 11:50:14 2014 -0700 @@ -82,6 +82,9 @@ bool canvasKeyPressEvent (QKeyEvent* event); bool canvasKeyReleaseEvent (QKeyEvent* event); + void updateCurrentPoint (const graphics_object& fig, + const graphics_object& obj, QMouseEvent *event); + private: graphics_handle m_handle; bool m_redrawBlocked; diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/Container.cc --- a/libgui/graphics/Container.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/Container.cc Fri Apr 04 11:50:14 2014 -0700 @@ -24,6 +24,7 @@ #include #endif +#include #include #include "graphics.h" @@ -95,4 +96,12 @@ } } +void Container::childEvent (QChildEvent* event) +{ + if (event->child ()->isWidgetType ()) + { + qobject_cast (event->child ())->setMouseTracking (hasMouseTracking ()); + } +} + }; // namespace QtHandles diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/Container.h --- a/libgui/graphics/Container.h Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/Container.h Fri Apr 04 11:50:14 2014 -0700 @@ -45,6 +45,7 @@ Canvas* canvas (const graphics_handle& handle, bool create = true); protected: + void childEvent (QChildEvent* event); void resizeEvent (QResizeEvent* event); private: diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/Figure.cc --- a/libgui/graphics/Figure.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/Figure.cc Fri Apr 04 11:50:14 2014 -0700 @@ -141,6 +141,12 @@ eventMask |= Canvas::KeyRelease; m_container->canvas (m_handle)->setEventMask (eventMask); + if (! fp.get_windowbuttonmotionfcn ().is_empty ()) + { + m_container->setMouseTracking (true); + m_container->canvas (m_handle)->qWidget ()->setMouseTracking (true); + } + connect (this, SIGNAL (asyncUpdate (void)), this, SLOT (updateContainer (void))); @@ -302,6 +308,15 @@ else m_container->canvas (m_handle)->addEventMask (Canvas::KeyRelease); break; + case figure::properties::ID_WINDOWBUTTONMOTIONFCN: + { + bool hasCallback = ! fp.get_windowbuttonmotionfcn ().is_empty (); + + m_container->setMouseTracking (hasCallback); + foreach (QWidget* w, m_container->findChildren ()) + { w->setMouseTracking (hasCallback); } + } + break; default: break; } diff -r aff86394c201 -r 37d5a2bb4160 libgui/graphics/Panel.cc --- a/libgui/graphics/Panel.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/graphics/Panel.cc Fri Apr 04 11:50:14 2014 -0700 @@ -115,6 +115,12 @@ m_container = new Container (frame); m_container->canvas (m_handle); + if (frame->hasMouseTracking ()) + { + foreach (QWidget* w, frame->findChildren ()) + { w->setMouseTracking (true); } + } + QString title = Utils::fromStdString (pp.get_title ()); if (! title.isEmpty ()) { diff -r aff86394c201 -r 37d5a2bb4160 libgui/languages/translators --- a/libgui/languages/translators Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/languages/translators Fri Apr 04 11:50:14 2014 -0700 @@ -11,3 +11,4 @@ ru_RU Andriy Shinkarchuck uk_UA Andriy Shinkarchuck nl_NL Sander van Rijn +zh_CN Jeff Bai diff -r aff86394c201 -r 37d5a2bb4160 libgui/languages/zh_CN.ts --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/languages/zh_CN.ts Fri Apr 04 11:50:14 2014 -0700 @@ -0,0 +1,2118 @@ + + + + + MIME-Version,Content-Type,Content-Transfer-Encoding,Plural-Forms,X-Language,X-Qt-Contexts,Project-Id-Version,POT-Creation-Date,PO-Revision-Date,Last-Translator,Language-Team,Language,X-Generator + Poedit 1.6.4 + 安同开源社区 <aosc@members.fsf.org> + octave + + zh_CN + Jeff Bai <jeffbaichina@members.fsf.org> + + ListDialog + + + Select All + 全选 + + + + QObject + + + automatic + 自动 + + + + function + 函数 + + + + global + 全局 + + + + hidden + 隐藏的 + + + + inherited + 继承的 + + + + persistent + 持续的 + + + + foreground + 前台 + + + + background + 后台 + + + + selection + 选择 + + + + cursor + 光标 + + + + <p><strong>A Note about Octave's New GUI</strong></p><p>One of the biggest new features for Octave 3.8 is a graphical user interface. It is the one thing that users have requested most often over the last few years and now it is almost ready. But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.</p><p>Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI. So please enjoy the 3.8 release of Octave and the preview of the new GUI. We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.</p><p><strong>We Need Your Help</strong></p><p>There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):</p><p><ul><li>If you are a skilled software developer, you can help by contributing your time to help <a href="http://octave.org/get-involved.html">develop Octave</a>.</li><li>If Octave does not work properly, you are encouraged to <a href="http://octave.org/bugs.html">report problems </a> that you find.</li><li>Whether you are a user or developer, you can <a href="http://octave.org/donate.html">help to fund the project</a>. Octave development takes a lot of time and expertise. Your contributions help to ensure that Octave will continue to improve.</li></ul></p><p>We hope you find Octave to be useful. Please help us make it even better for the future!</p> + <p><strong>关于 Octave 新用户界面的一点注意事项</strong></p><p>Octave 最重要的一个新特性就是图形界面。这是用户在过往几年需求最大、最多的一个特性,现在这个界面终于基本就绪了。但是这个界面现在恐怕还不特别完善、尚需打磨,所以我们计划在 4.0.x 发行系列才将图形界面作为默认的用户界面。</p><p>考虑到这个版本的和上个主要版本之间开发时长和修复的 Bug 数量还有一部分的改进,我们决定不再推迟发行以打磨界面。所以请尽情享用 Octave 的 3.8 版本以及新界面的预览吧。我们认为这个版本已经相当可用,不过我们也知道这个发行存在一定量的粗糙细节和很多可以做得更好的地方。</p><p><strong>我们需要你的帮助</strong></p><p>你有很多方法可以帮助我们处理依然存在的问题,完善用户界面,并给专家和新手们改进用户体验 (以下链接会打开外部浏览器):</p><p><ul><li>如果你是一个有一定经验的软件爱你开发者,你可以使用你的闲时来帮助我们 <a href="http://octave.org/get-involved.html">develop Octave</a>。</li><li>如果 Octave 工作不正常,我们鼓励你 <a href="http://octave.org/bugs.html">报告问题</a>。</li><li>无论你是开发者还是用户,你可以 <a href="http://octave.org/donate.html">资助我们</a>。Octave 的开发需要大量时间和经验。你的贡献让我们有信心让 Octave 继续变得更好。</li></ul></p><p>我们希望 Octave 可以给你带来一定的帮助。请帮助我们让 Octave 的未来变得更好!</p> + + + + QTerminal + + + Copy + 复制 + + + + Paste + 粘贴 + + + + Clear All + 清空 + + + + QWinTerminalImpl + + + copied selection to clipboard + 复制选定区域到剪贴板 + + + + documentation_dock_widget + + + Documentation + 文档 + + + + See the documentation for help. + 阅读文档以获取帮助。 + + + + file_editor + + + + + + + Octave Editor + Octave 编辑器 + + + + Octave Files (*.m);;All Files (*) + Octave 文件 (*.m);;所有文件 (*) + + + + New Function + 新建函数 + + + + New function name: + + 新建函数的名称: + + + + + File not saved! A file with the selected name +%1 +is already open in the editor + 文件未保存!一个带有相同名称 +%1 +的文件在编辑器中被打开 + + + + &%1 %2 + &%1 %2 + + + + &New File + 新建文件 (&N) + + + + &Save File + 保存文件 (&S) + + + + &Open File... + 打开文件 (&O) ... + + + + Save File &As... + 文件另存为 (&A)... + + + + Print... + 打印... + + + + &Undo + 撤销 (&U) + + + + &Redo + 重做 (&R) + + + + &Copy + 复制 (&C) + + + + Cu&t + 剪切 (&T) + + + + Paste + 粘贴 + + + + &Next Bookmark + 下一个书签 (&N) + + + + Pre&vious Bookmark + 上一个书签 (&V) + + + + Toggle &Bookmark + 打开/关闭书签 (&B) + + + + &Remove All Bookmarks + 移除所有书签 (&R) + + + + &Next Breakpoint + 下一个断点 (&N) + + + + Pre&vious Breakpoint + 上一个断点 (&V) + + + + Toggle &Breakpoint + 打开/关闭断点 (&B) + + + + &Remove All Breakpoints + 移除所有断点 (&R) + + + + &Comment + 注释 (&C) + + + + &Uncomment + 取消注释 (&U) + + + + &Find and Replace... + 查找并替换 (&F) ... + + + + Save File and Run + 保存文件并运行 + + + + Go &to Line... + 跳至行 (&T) ... + + + + &Recent Editor Files + 最近编辑器文件 (&R) + + + + &Edit Function + 编辑函数 (&E) + + + + &Close + 关闭 (&C) + + + + Close All + 关闭全部 + + + + Close Other Files + 关闭其他文件 + + + + &Preferences... + 首选项 (&P) ... + + + + &Styles Preferences... + 风格首选项 (&S) ... + + + + Run &Selection + 运行选定部分 (&S) + + + + &Help + 帮助 (&H) + + + + &Help on Keyword + 帮助关键字 (&H) + + + + &Documentation on Keyword + 文档关键字 (&D) + + + + Could not open file +%1 +for read: %2. + 数据文件 +%1 +无法打开/读取: %2. + + + + File +%1 +does not exist. Do you want to create it? + 数据文件 +%1 +不存在。你希望创建它么? + + + + Could not open file +%1 +for write: %2. + 数据文件 +%1 +无法打开/写入: %2. + + + + The associated file editor tab has disappeared. + 关联文件的编辑标签消失了。 + + + + &File + 文件 (&F) + + + + New &Function... + 新建函数 (&F) ... + + + + &Edit + 编辑 (&E) + + + + &Debug + 除错 (&D) + + + + &Run + 运行 (&R) + + + + file_editor_tab + + + Goto line + 前往行 + + + + Line number + 行数 + + + + + <unnamed> + <未命名> + + + + Do you want to save or discard the changes? + 你希望保存还是丢弃更改? + + + + Do you want to cancel closing, save or discard the changes? + 你希望关闭,保存还是丢弃更改? + + + + + + + Octave Editor + Octave 编辑器 + + + + The file +%1 +is about to be closed but has been modified. +%2 + 数据文件 +%1 +即将要被关闭,但是它已经被更改。 +%2 + + + + Octave Files (*.m);;All Files (*) + Octave 文件 (*.m);;所有文件 (*) + + + + + +Warning: The contents in the editor is modified! + + +警告: 编辑器中内容已经被修改! + + + + It seems that the file +%1 +has been deleted or renamed. Do you want to save it now?%2 + 数据文件 +%1 +已经被修改或重命名。你希望现在保存这个文件吗?%2 + + + + Could not open file %1 for write: +%2. + 无法打开文件 %1 以写入: +%2. + + + + Line: + 行: + + + + Col: + 列: + + + + It seems that '%1' has been modified by another application. Do you want to reload it? + 看起来 '%1' 已经被其他应用修改。你希望重新载入这个文件吗? + + + + files_dock_widget + + + File Browser + 文件浏览器 + + + + Browse your files. + 浏览你的文件。 + + + + Enter the path or filename + 输入路径或文件名 + + + + Move up one directory + 向上一级移动 + + + + Actions on current directory + 在当前目录的操作 + + + + Find Files... + 查找文件... + + + + New File + 新建文件 + + + + New Directory + 新建目录 + + + + Double-click a file to open it + 双击一个文件以打开它 + + + + Show Octave directory + 显示 Octave 目录 + + + + Go to current Octave directory + 前往当前的 Octave 目录 + + + + Set Octave directory + 设置 Octave 目录 + + + + Set Octave directroy to current browser directory + 设置 Octave 路径为当前浏览的目录 + + + + Show Home Directory + 显示主目录 + + + + Search Directory... + 搜索目录... + + + + New File... + 新建文件... + + + + New Directory... + 新建目录... + + + + File size + 文件大小 + + + + File type + 文件类型 + + + + Date modified + 修改日期 + + + + Show hidden + 显示隐藏文件 + + + + Open + 打开 + + + + Open in Default Application + 使用默认应用程序打开 + + + + Copy Selection to Clipboard + 复制选中到剪贴板 + + + + Run + 运行 + + + + Load Data + 载入数据 + + + + Set Current Directory + 设置当前目录 + + + + Rename + 重命名 + + + + Delete + 删除 + + + + Rename file/directory + 重命名文件/目录 + + + + Rename file/directory: + + 重命名文件/目录: + + + + + + to: + +到: + + + + + Delete file/directory + 删除文件/目录 + + + + Are you sure you want to delete + + 你确实希望删除 + + + + + Can not delete a directory that is not empty + 不能删除一个非空目录 + + + + Set directory of file browser + 设置目录到文件浏览器 + + + + Create File + 创建文件 + + + + Create file in + + String ends with \n! + 创建文件于 + + + + + Create Directory + 创建目录 + + + + Create folder in + + String ends with \n! + 创建目录于 + + + + + final_page + + + Enjoy! + 尽情享受吧! + + + + Previous + 上一个 + + + + Finish + 完成 + + + + Cancel + 取消 + + + + <html><body> +<p>We hope you find Octave to be a useful tool.</p> +<p>If you encounter problems, there are a number of ways to get help, including commercial support options, a mailing list, a wiki, and other commnity-based support channels. +You can find more information about each of these by visiting <a href="http://octave.org/support.html">http://octave.org/support.html</a> (opens in external browser).</p> +</body></html> + <html><body> +<p>我们希望 Octave 能给你带来便利和帮助。</p> +<p>当你在使用过程中遇到问题时,有许多办法获取帮助,包括商业支持选项、一个邮件列表、一个百科以及其他社区的支持频道。 +你也可以访问这里以获取更多的信息 <a href="http://octave.org/support.html">http://octave.org/support.html</a> (将会在外部浏览器打开)。</p> +</body></html> + + + + <html><head> +<style> +a:link { text-decoration: underline; color: #0000ff; } +</style> +<head/><body> +<p>For more information about Octave:</p> +<ul> +<li>Visit <a href="http://octave.org">http://octave.org</a> (opens in external browser)</li> +<li>Get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html">html</a>- or <a href="http://www.gnu.org/software/octave/octave.pdf">pdf</span></a>-document (opens in external browser)</li> +<li>Open the documentation browser of the Octave GUI with the help menu</li> +</ul> +</body></html> + <html><head> +<style> +a:link { text-decoration: underline; color: #0000ff; } +</style> +<head/><body> +<p>欲了解更多关于 Octave 的信息: </p> +<ul> +<li>访问 <a href="http://octave.org">http://octave.org</a> (在外部浏览器打开)</li> +<li>从 <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html">html</a>- 或 <a href="http://www.gnu.org/software/octave/octave.pdf">获取 PDF 格式的</span></a>-文档 (在外部浏览器打开)</li> +<li>在 Octave GUI 的帮助菜单打开帮助文档。</li> +</ul> +</body></html> + + + + find_dialog + + + Find &what: + 搜索 (&W) : + + + + Re&place with: + 替换为 (&P) : + + + + Match &case + 匹配大小写 (&C) + + + + Search from &start + 从开头搜索 (&S) + + + + &Wrap while searching + 搜索时循环 (&W) + + + + &Find Next + 查找下一个 (&F) + + + + Find &Previous + 查找上一个 (&P) + + + + &Replace + 替换 (&R) + + + + Replace &All + 替换全部 (&A) + + + + &More... + 更多 (&M) ... + + + + &Whole words + 整个单词 (&W) + + + + Regular E&xpressions + 常规表达式 (&X) + + + + Search &backward + 反向搜索 (&B) + + + + Search se&lection + 搜索选中 (&L) + + + + Search from end + 从尾部搜索 + + + + Search from start + 从开头搜索 + + + + Replace Result + 替换结果 + + + + %1 items replaced + %1 项已替换 + + + + Find Result + 查找结果 + + + + No more matches found + 没有更多匹配项 + + + + find_files_dialog + + + Find Files + 查找文件 + + + + Named: + 名称: + + + + Enter the filename expression + 输入文件名表达式 + + + + Start in: + 从: + + + + Enter the start directory + 进入初始目录 + + + + Browse... + 浏览... + + + + Browse for start directory + 从初始目录浏览 + + + + Recurse directories + 递归目录 + + + + Search recursively through directories for matching files + 递归搜索目录以查找匹配文件 + + + + Include directories + 包含目录 + + + + Include matching directories in search results + 在搜索结果中包含匹配目录 + + + + Name case insensitive + 名称大小写敏感 + + + + Set matching name is case insensitive + 设置匹配名称大小写敏感 + + + + Contains text: + 包含文字: + + + + Search must match text + 搜索必须匹配文字 + + + + Text to match + 要匹配的文字 + + + + Text case insensitive + 文字大小写敏感 + + + + Set text content is case insensitive + 设置文字内容大小写敏感 + + + + Search results + 搜索结果 + + + + Idle. + 空闲。 + + + + Find + 查找 + + + + Start search for matching files + 开始查找匹配文件 + + + + Stop + 停止 + + + + Stop searching + 停止搜索 + + + + File name/location + 文件名称/位置 + + + + File contents + 文件内容 + + + + Searching... + 正在搜索... + + + + Set search directory + 设置搜索目录 + + + + find_files_model + + + Filename + 文件名 + + + + Directory + 目录 + + + + history_dock_widget + + + Browse and search the command history. + 浏览并搜索命令历史。 + + + + Double-click a command to transfer it to the terminal. + 双击一个命令以传递到终端。 + + + + Enter text to filter the command history. + 输入文字以过滤命令历史。 + + + + Command History + 命令历史 + + + + Copy + 复制 + + + + Evaluate + 评估 + + + + Create script + 创建脚本 + + + + initial_page + + + Welcome to Octave! + 欢迎来到 Octave! + + + + Next + 下一个 + + + + Cancel + 取消 + + + + <html><body> +<p>You seem to be using the Octave graphical interface for the first time on this computer. +Click 'Next' to create a configuration file and launch Octave.</p> +<p>The configuration file is stored in<br>%1.</p> +</body></html> + <html><body> +<p>看起来这是你第一次在这台电脑上使用 Octave 图形界面。 +点击 '下一步' 以创建一个配置文件并启动 Octave .</p> +<p>配置文件存放于<br>%1.</p> +</body></html> + + + + main_window + + + Load Workspace + 载入工作空间 + + + + + About Octave + 关于 Octave + + + + &File + 文件 (&F) + + + + New + 新建 + + + + Script + 脚本 + + + + Figure + 图形 + + + + Open... + 打开... + + + + Preferences... + 首选项... + + + + Exit + 退出 + + + + &Edit + 编辑 (&E) + + + + Undo + 撤销 + + + + Copy + 复制 + + + + Paste + 粘贴 + + + + Save Workspace As + 工作空间另存为 + + + + The release notes file '%1' is empty. + 发行注记文件 '%1' 是空的。 + + + + The release notes file '%1' cannot be read. + 发行注记文件 '%1' 无法读取。 + + + + Octave Release Notes + Octave 发行注记 + + + + Octave Community News + Octave 社区新闻 + + + + Clear Clipboard + 清空剪贴板 + + + + Find Files... + 查找文件... + + + + Clear Command Window + 清空命令窗口 + + + + Clear Command History + 清空命令历史 + + + + Clear Workspace + 清空工作空间 + + + + De&bug + 除错 (&B) + + + + Step + 步骤 + + + + Continue + 继续 + + + + Exit Debug Mode + 退出除错模式 + + + + Show File Browser + 显示文件浏览器 + + + + File Browser + 文件浏览器 + + + + <strong>You are using a release candidate of Octave's experimental GUI.</strong> Octave is under continuous improvement and the GUI will be the default interface for the 4.0 release. For more information, select the "Release Notes" item in the "News" menu of the GUI, or visit <a href="http://octave.org">http://octave.org</a>. + <strong>你正在使用一个候选发布版本的 Octave GUI .</strong> Octave 目前正在不停改进以让此图形界面成为 4.0 的默认界面。欲了解更多详情,请选择 GUI 中 "新闻" 目录下的 "发行注记",或访问 <a href="http://octave.org">http://octave.org</a>. + + + + Step In + 步进 + + + + Load Workspace... + 载入工作空间... + + + + Save Workspace As... + 工作空间另存为... + + + + Function... + 函数... + + + + Step Out + 步出 + + + + Reset Default Window Layout + 复位为默认窗口布局 + + + + Octave Packages + Octave 软件包 + + + + Share Code + 共享代码 + + + + Contribute to Octave + 贡献 Octave + + + + Octave Developer Resources + Octave 开发者资源 + + + + On Disk + 磁盘上 + + + + Online + 在线 + + + + &News + 新闻 (&N) + + + + Release Notes + 发行注记 + + + + Community News + 社区新闻 + + + + More Info + 更多信息 + + + + Hide + 隐藏 + + + + + Experimental GUI Info + 实验性 GUI 信息 + + + + Enter directory name + 输入目录名 + + + + Current Directory: + 当前目录: + + + + One directory up + 向上一级 + + + + + Browse directories + 浏览目录 + + + + &Window + 窗口 (&W) + + + + Show Command Window + 显示命令窗口 + + + + Show Command History + 显示命令历史 + + + + Show Workspace + 显示工作空间 + + + + Show Editor + 显示编辑器 + + + + Show Documentation + 显示文档 + + + + Command Window + 命令窗口 + + + + Command History + 命令历史 + + + + Workspace + 工作空间 + + + + Editor + 编辑器 + + + + + Documentation + 文档 + + + + &Help + 帮助 (&H) + + + + Report Bug + 报告问题 + + + + news_reader + + + <html> +<body> +<p> +Octave's community news source seems to be unavailable. +</p> +<p> +For the latest news, please check +<a href="http://octave.org/community-news.html">http://octave.org/community-news.html</a> +when you have a connection to the web (link opens in an external browser). +</p> +<p> +<small><em>&mdash; The Octave Developers, + <html> +<body> +<p> +Octave 的社区新闻来源似乎不可用。 +</p> +<p> +当你的网络连接可用时,要获取最新新闻,请查阅 +<a href="http://octave.org/community-news.html">http://octave.org/community-news.html</a> +(将在外部浏览器打开) . +</p> +<p> +<small><em>&mdash; Octave 开发者 + + + + <html> +<body> +<p> +Connecting to the web to display the latest Octave Community news has been disabled. +</p> +<p> +For the latest news, please check +<a href="http://octave.org/community-news.html">http://octave.org/community-news.html</a> +when you have a connection to the web (link opens in an external browser) +or enable web connections for news in Octave's network settings dialog. +</p> +<p> +<small><em>&mdash; The Octave Developers, + <html> +<body> +<p> +连接到互联网以获取 Octave 社区新闻的选项已经被禁用。 +</p> +<p> +在网络连接可用时,要获取最新新闻,请查阅 +<a href="http://octave.org/community-news.html">http://octave.org/community-news.html</a> +(将在外部浏览器打开链接)。 +或者在 Octave 网络设置对话框打开网络连接。 +</p> +<p> +<small><em>&mdash; Octave 开发者 + + + + octave_dock_widget + + + + Undock widget + 移动挂件 + + + + Hide widget + 隐藏挂件 + + + + Dock widget + 停靠挂件 + + + + octave_qscintilla + + + Help on + 开启帮助 + + + + Documentation on + 开启文档 + + + + Edit + 编辑 + + + + &Run Selection + 运行选定项 (&R) + + + + octave_qt_link + + + + + Yes + + + + + No + + + + + File +%1 +does not exist. Do you want to create it? + 文件 +%1 +不存在。你希望创建它吗? + + + + Octave Editor + Octave 编辑器 + + + + The file %1 does not exist in the load path. To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path. + 文件 %1 不存在于载入路径。要给当前编辑的函数除错,你必须切换到目录 %2 或添加那个目录到载入路径。 + + + + The file %1 is shadowed by a file with the same name in the load path. To debug the function you are editing, change to the directory %2. + 文件 %1 在相同目录被创建影子文件。要给当前编辑的函数除错,请切换到目录 %2 . + + + + Change Directory or Add Directory to Load Path + 切换目录或添加目录到载入路径 + + + + Change Directory + 切换目录 + + + + Add Directory to Load Path + 添加目录到载入路径 + + + + Cancel + 取消 + + + + resource_manager + + + The settings file +%1 +does not exist and can not be created. +Make sure you have read and write permissions to +%2 + +Octave GUI must be closed now. + 配置文件 +%1 +不存在且不能被创建。 +请确定你在如下目录有写入权限。 +%2 +besitzt. +Die Octave Benutzeroberfläche muss jetzt geschlossen werden. + + + + Octave Critical Error + Octave 严重错误 + + + + settings_dialog + + + Settings + 设置 + + + + General + 常规 + + + + Octave logo only + 仅 Octave 徽标 + + + + Letter icons + 字母图标 + + + + Editor + 编辑器 + + + + Color + 颜色 + + + + Indent width + 缩进宽度 + + + + Tab indents line + Tab 键缩进行 + + + + Auto indentation + 自动缩进 + + + + Tab width + Tab 键宽度 + + + + Show indentation guides + 显示缩进参考线 + + + + Backspace unindents line + 退格键删除缩进符 + + + + Match keywords + 匹配关键字 + + + + Case sensitive + 大小写敏感 + + + + Replace word by suggested one + 使用建议的单词替换原有的 + + + + Match words in document + 在文档中匹配单词 + + + + Restore editor tabs from previous session on startup + 在启动时恢复上次会话的编辑器标签 + + + + Use custom file editor + 使用自定义文件编辑器 + + + + Editor Styles + 编辑器风格 + + + + <html><head/><body><p>Select font, font size (as a difference from the default size), font style (<b>b</b>old, <b>i</b>talic, <b>u</b>nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).</p></body></html> + <html><head/><body><p>选择字体和字体大小 (和默认大小不同),以及字体风格 (<b>粗</b>体, <b>斜</b>体, <b>下</b>划线), 文字颜色和背景色 (对于后者,粉红色 (255,0,255) 是默认背景颜色的占位符)。</p></body></html> + + + + Terminal Colors + 终端颜色 + + + + Font + 字体 + + + + Show line numbers + 显示行数 + + + + Highlight current line + 高亮当前行 + + + + Code completion + 代码补全 + + + + Show complete path in window title + 在窗口标题显示完整路径 + + + + Graphic icons + 图形图标 + + + + Show whitespace + 显示空白 + + + + Do not show whitespace used for indentation + 不要显示缩进的空白空间 + + + + # of characters typed before completion list displayed + 在补全列表显示前输入字符的数量 + + + + Create nonexistent files without prompting + 在创建不存在的文件时不提示 + + + + command line (%f=file, %l=line): + 命令行 (%f=文件, %l=行数): + + + + emacs + Emacs + + + + Terminal + 终端 + + + + Cursor type: + 光标类型: + + + + Cursor blinking + 光标闪烁 + + + + Use foreground color + 使用前景色 + + + + Font size + 字体大小 + + + + File Browser + 文件浏览器 + + + + Show file size + 显示文件大小 + + + + Show file type + 显示文件类型 + + + + Show date of last modification + 显示最后修改日期 + + + + Show hidden files + 显示隐藏文件 + + + + Alternating row colors + 备选列颜色 + + + + Workspace + 工作空间 + + + + Storage Class Colors + 存储类颜色 + + + + Network + 网络 + + + + Allow Octave to connect to the Octave web site to display current news and information + 允许 Octave 连接到 Octave 站点以显示当前新闻和信息 + + + + Use proxy server + 使用代理服务器 + + + + HttpProxy + HTTP Proxy + + + + Icon set for dock widgets + 挂件的图标集 + + + + Language (requires restart) + 语言 (需要重启) + + + + Icon size + 图标大小 + + + + Synchronize Octave working directory with file browser + 使用文件浏览器同步 Octave 工作目录 + + + + Socks5Proxy + Socks5Proxy + + + + Hostname: + 主机名: + + + + Proxy type: + 代理类型: + + + + Port: + 端口: + + + + Username: + 用户名: + + + + Password: + 密码: + + + + + + System setting + 系统设置 + + + + IBeam Cursor + IBeam 光标 + + + + Block Cursor + 块状光标 + + + + Underline Cursor + 给光标添加下划线 + + + + Difference to the default size + 和默认大小的差别 + + + + Background color, pink (255,0,255) means default + 背景颜色,粉红色 (255,0,255) 代表默认值 + + + + b + short form for bold + b + + + + i + short form for italic + i + + + + u + short form for underlined + u + + + + setup_community_news + + + Community News + 社区新闻 + + + + Previous + 上一个 + + + + Next + 下一个 + + + + Cancel + 取消 + + + + <html><body> +<p>When the Octave GUI starts, it will check the Octave web site for current news and information about the Octave community. +The check will happen at most once each day and news will only be displayed if there is something new since the last time you viewed the news.</p> +<p>You may also view the news by selecting the "Community News" item in the "Help" menu in the GUI, or by visiting +<a href="http://octave.org/community-news.html">http://octave.org/community-news.html</a>.</p> +</body></html> + <html><body> +<p>当 Octave GUI 启动的时候,它会检查 Octave 站点上关于 Octave 社区的新闻和信息。 +每天会检查一次新闻消息,而只有在你上次阅读新闻起有新的新闻出现时才会弹出。</p> +<p>你也可以点选 GUI 上的 "社区新闻" 以直接阅读新闻,或直接访问: +<a href="http://octave.org/community-news.html">http://octave.org/community-news.html</a>.</p> +</body></html> + + + + <html><head> +<style> +a:link { text-decoration: underline; color: #0000ff; } +</style> +<head/><body> +<p>Allow Octave to connect to the Octave web site when it starts to display current news and information about the Octave community.</p> +</body></html> + <html><head> +<style> +a:link { text-decoration: underline; color: #0000ff; } +</style> +<head/><body> +<p>允许 Octave 在显示关于 Octave 社区的新闻和信息时连接到 Octave 站点。</p> +</body></html> + + + + terminal_dock_widget + + + Command Window + 命令窗口 + + + + webinfo + + + Type here and press 'Return' to search + 在这里输入并按下回车以搜索 + + + + Global search + 全局搜索 + + + + welcome_wizard + + + Welcome to GNU Octave + 欢迎来到 GNU Octave + + + + workspace_model + + + Name + 名称 + + + + Class + + + + + Dimension + 维度 + + + + Value + + + + + Storage Class + 存储类 + + + + Right click to copy, rename, or display + 右击以复制,重命名或显示 + + + + + complex + 复杂度 + + + + workspace_view + + + Workspace + 工作区 + + + + View the variables in the active workspace. + 显示当前活动工作区的变量。 + + + + Copy + 复制 + + + + Rename + 重命名 + + + + Only top-level symbols may be renamed. + 只有顶级符号才能被重命名。 + + + + View the variables in the active workspace.<br> + 显示当前活动工作区的变量。<br> + + + + Colors for the storage class: + 存储类的颜色: + + + diff -r aff86394c201 -r 37d5a2bb4160 libgui/qterminal/libqterminal/QTerminal.cc --- a/libgui/qterminal/libqterminal/QTerminal.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/qterminal/libqterminal/QTerminal.cc Fri Apr 04 11:50:14 2014 -0700 @@ -118,4 +118,5 @@ (cursorUseForegroundColor, settings->value ("terminal/color_c", QVariant (colors.at (3))).value ()); + setScrollBufferSize (settings->value ("terminal/history_buffer",1000).toInt() ); } diff -r aff86394c201 -r 37d5a2bb4160 libgui/qterminal/libqterminal/QTerminal.h --- a/libgui/qterminal/libqterminal/QTerminal.h Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/qterminal/libqterminal/QTerminal.h Fri Apr 04 11:50:14 2014 -0700 @@ -81,6 +81,8 @@ virtual void setCursorColor (bool useForegroundColor, const QColor& color) = 0; + virtual void setScrollBufferSize(int value=1000) = 0; + signals: void report_status_message (const QString&); diff -r aff86394c201 -r 37d5a2bb4160 libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp --- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp Fri Apr 04 11:50:14 2014 -0700 @@ -69,13 +69,23 @@ m_terminalModel = new TerminalModel(m_kpty); m_terminalModel->setAutoClose(true); m_terminalModel->setCodec(QTextCodec::codecForName("UTF-8")); - m_terminalModel->setHistoryType(HistoryTypeBuffer(1000)); + m_terminalModel->setHistoryType(HistoryTypeBuffer (1000)); m_terminalModel->setDarkBackground(true); m_terminalModel->setKeyBindings(""); m_terminalModel->run(); m_terminalModel->addView(m_terminalView); connectToPty(); } +void QUnixTerminalImpl::setScrollBufferSize(int value) +{ + if (value > 0) + { + m_terminalModel->clearHistory (); + m_terminalModel->setHistoryType (HistoryTypeBuffer ( value )); + } + else + m_terminalModel->setHistoryType (HistoryTypeNone ()); +} void QUnixTerminalImpl::connectToPty() { diff -r aff86394c201 -r 37d5a2bb4160 libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h --- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h Fri Apr 04 11:50:14 2014 -0700 @@ -47,7 +47,7 @@ void setForegroundColor (const QColor& color); void setSelectionColor (const QColor& color); void setCursorColor (bool useForegroundColor, const QColor& color); - + void setScrollBufferSize(int value); QString selectedText(); public slots: diff -r aff86394c201 -r 37d5a2bb4160 libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp --- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp Fri Apr 04 11:50:14 2014 -0700 @@ -205,6 +205,7 @@ void setForegroundColor (const QColor& color); void setSelectionColor (const QColor& color); void setCursorColor (bool useForegroundColor, const QColor& color); + void setScrollBufferSize (int value); void drawTextBackground (QPainter& p, int cx1, int cy1, int cx2, int cy2, int cw, int ch); @@ -597,6 +598,14 @@ m_cursorColor = useForegroundColor ? QColor () : color; } +void QConsolePrivate::setScrollBufferSize (int value) +{ +// FIXME: not tested code follows +// CONSOLE_SCREEN_BUFFER_INFO sbi; +// GetConsoleScreenBufferInfo (m_stdOut, &sbi); +// m_bufferSize = QSize (sbi.dwSize.X, qMax (sbi.dwSize.Y, (SHORT)value)); +} + void QConsolePrivate::drawTextBackground (QPainter& p, int cx1, int cy1, int cx2, int cy2, int cw, int ch) { @@ -1512,6 +1521,13 @@ d->setCursorColor (useForegroundColor, color); } +void QWinTerminalImpl::setScrollBufferSize(int value) +{ +// FIXME: not tested code follows +// d->setScrollBufferSize (value); +} + + ////////////////////////////////////////////////////////////////////////////// void QWinTerminalImpl::setTerminalFont (const QFont& f) diff -r aff86394c201 -r 37d5a2bb4160 libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h --- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h Fri Apr 04 11:50:14 2014 -0700 @@ -60,6 +60,7 @@ void setForegroundColor (const QColor& color); void setSelectionColor (const QColor& color); void setCursorColor (bool useForegoundColor, const QColor& color); + void setScrollBufferSize(int value); QString selectedText (); diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/dialog.cc --- a/libgui/src/dialog.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/dialog.cc Fri Apr 04 11:50:14 2014 -0700 @@ -485,23 +485,25 @@ string_result = selectedFiles (); + if (testOption (QFileDialog::ShowDirsOnly) == true && + string_result.size () > 0) + { + path = string_result[0]; + } + else + { + path = directory ().absolutePath (); + } + // Matlab expects just the file name, whereas the file dialog gave us - // pull path names, so fix it. + // full path names, so fix it. for (int i = 0; i < string_result.size (); i++) string_result[i] = QFileInfo (string_result[i]).fileName (); - path = directory ().absolutePath (); - // if not showing only dirs, add end slash for the path component if (testOption (QFileDialog::ShowDirsOnly) == false) path = path + "/"; - else - { - // if name was provided in uigetdir, add to path - if (string_result.size() > 0) - path = path + "/" + string_result[0]; - } // convert to native slashes path = QDir::toNativeSeparators (path); diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/m-editor/file-editor.cc --- a/libgui/src/m-editor/file-editor.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/m-editor/file-editor.cc Fri Apr 04 11:50:14 2014 -0700 @@ -28,6 +28,8 @@ #include "file-editor.h" #include "resource-manager.h" +#include "shortcut-manager.h" + #include #include #include @@ -1552,6 +1554,10 @@ { if (set) { + + shortcut_manager::set_shortcut (_save_action, "editor_file:save"); + shortcut_manager::set_shortcut (_save_as_action, "editor_file:save_as"); + _comment_selection_action->setShortcut (Qt::ControlModifier + Qt::Key_R); _uncomment_selection_action->setShortcut (Qt::SHIFT + Qt::ControlModifier @@ -1586,12 +1592,11 @@ _context_run_action->setShortcut (Qt::Key_F9); _context_edit_action->setShortcut (Qt::ControlModifier + Qt::Key_E); - _save_action->setShortcut (QKeySequence::Save); - _save_as_action->setShortcut (QKeySequence::SaveAs); _close_action->setShortcut (QKeySequence::Close); _redo_action->setShortcut (QKeySequence::Redo); _undo_action->setShortcut (QKeySequence::Undo); + } else { diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/main-window.cc --- a/libgui/src/main-window.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/main-window.cc Fri Apr 04 11:50:14 2014 -0700 @@ -51,6 +51,7 @@ #endif #include "main-window.h" #include "settings-dialog.h" +#include "shortcut-manager.h" #include "__init_qt__.h" @@ -680,6 +681,9 @@ int icon_size = settings->value ("toolbar_icon_size",16).toInt (); _main_tool_bar->setIconSize (QSize (icon_size,icon_size)); + set_global_shortcuts (true); + set_global_shortcuts (command_window_has_focus ()); + resource_manager::update_network_settings (); } @@ -1442,15 +1446,15 @@ file_menu->addSeparator (); - QAction *load_workspace_action + _load_workspace_action = file_menu->addAction (tr ("Load Workspace...")); - QAction *save_workspace_action + _save_workspace_action = file_menu->addAction (tr ("Save Workspace As...")); file_menu->addSeparator (); - QAction *preferences_action + _preferences_action = file_menu->addAction (QIcon (":/actions/icons/configure.png"), tr ("Preferences...")); @@ -1459,7 +1463,7 @@ _exit_action = file_menu->addAction (tr ("Exit")); _exit_action->setShortcutContext (Qt::ApplicationShortcut); - connect (preferences_action, SIGNAL (triggered ()), + connect (_preferences_action, SIGNAL (triggered ()), this, SLOT (process_settings_dialog_request ())); #ifdef HAVE_QSCINTILLA @@ -1467,10 +1471,10 @@ editor_window, SLOT (request_open_file ())); #endif - connect (load_workspace_action, SIGNAL (triggered ()), + connect (_load_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_load_workspace_request ())); - connect (save_workspace_action, SIGNAL (triggered ()), + connect (_save_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_save_workspace_request ())); connect (_exit_action, SIGNAL (triggered ()), @@ -1491,8 +1495,8 @@ _new_function_action->setEnabled (true); _new_function_action->setShortcutContext (Qt::ApplicationShortcut); - QAction *new_figure_action = new_menu->addAction (tr ("Figure")); - new_figure_action->setEnabled (true); + _new_figure_action = new_menu->addAction (tr ("Figure")); + _new_figure_action->setEnabled (true); #ifdef HAVE_QSCINTILLA connect (_new_script_action, SIGNAL (triggered ()), @@ -1502,7 +1506,7 @@ editor_window, SLOT (request_new_function ())); #endif - connect (new_figure_action, SIGNAL (triggered ()), + connect (_new_figure_action, SIGNAL (triggered ()), this, SLOT (handle_new_figure_request ())); } @@ -1515,22 +1519,18 @@ _undo_action = edit_menu->addAction (QIcon (":/actions/icons/undo.png"), tr ("Undo")); - _undo_action->setShortcut (QKeySequence::Undo); edit_menu->addSeparator (); _copy_action = edit_menu->addAction (QIcon (":/actions/icons/editcopy.png"), tr ("Copy"), this, SLOT (copyClipboard ())); - _copy_action->setShortcut (QKeySequence::Copy); - _paste_action = edit_menu->addAction (QIcon (":/actions/icons/editpaste.png"), tr ("Paste"), this, SLOT (pasteClipboard ())); - _paste_action->setShortcut (QKeySequence::Paste); - - QAction * select_all_action + + _select_all_action = edit_menu->addAction (tr ("Select All"), this, SLOT (selectAll ())); _clear_clipboard_action @@ -1543,25 +1543,25 @@ edit_menu->addSeparator (); - QAction *clear_command_window_action + _clear_command_window_action = edit_menu->addAction (tr ("Clear Command Window")); - QAction *clear_command_history + _clear_command_history_action = edit_menu->addAction (tr ("Clear Command History")); - QAction *clear_workspace_action + _clear_workspace_action = edit_menu->addAction (tr ("Clear Workspace")); connect (_find_files_action, SIGNAL (triggered ()), this, SLOT (find_files ())); - connect (clear_command_window_action, SIGNAL (triggered ()), + connect (_clear_command_window_action, SIGNAL (triggered ()), this, SLOT (handle_clear_command_window_request ())); - connect (clear_command_history, SIGNAL (triggered ()), + connect (_clear_command_history_action, SIGNAL (triggered ()), this, SLOT (handle_clear_history_request ())); - connect (clear_workspace_action, SIGNAL (triggered ()), + connect (_clear_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_clear_workspace_request ())); connect (_clipboard, SIGNAL (changed (QClipboard::Mode)), @@ -2282,17 +2282,26 @@ if (set_shortcuts) { - _open_action->setShortcut (QKeySequence::Open); - _new_script_action->setShortcut (QKeySequence::New); - _new_function_action->setShortcut (Qt::ControlModifier - + Qt::ShiftModifier - + Qt::Key_N); - - _exit_action->setShortcut (QKeySequence::Quit); - - _find_files_action->setShortcut (Qt::ControlModifier - + Qt::ShiftModifier - + Qt::Key_F); + // file menu + shortcut_manager::set_shortcut (_open_action, "main_file:open_file"); + shortcut_manager::set_shortcut (_new_script_action, "main_file:new_file"); + shortcut_manager::set_shortcut (_new_function_action, "main_file:new_function"); + shortcut_manager::set_shortcut (_new_function_action, "main_file:new_figure"); + shortcut_manager::set_shortcut (_load_workspace_action, "main_file:load_workspace"); + shortcut_manager::set_shortcut (_save_workspace_action, "main_file:save_workspace"); + shortcut_manager::set_shortcut (_preferences_action, "main_file:preferences"); + shortcut_manager::set_shortcut (_exit_action,"main_file:exit"); + + // edit menu + shortcut_manager::set_shortcut (_copy_action, "main_edit:copy"); + shortcut_manager::set_shortcut (_paste_action, "main_edit:paste"); + shortcut_manager::set_shortcut (_undo_action, "main_edit:undo"); + shortcut_manager::set_shortcut (_select_all_action, "main_edit:select_all"); + shortcut_manager::set_shortcut (_clear_clipboard_action, "main_edit:clear_clipboard"); + shortcut_manager::set_shortcut (_find_files_action, "main_edit:find_in_files"); + shortcut_manager::set_shortcut (_clear_command_history_action, "main_edit:clear_history"); + shortcut_manager::set_shortcut (_clear_command_window_action, "main_edit:clear_command_window"); + shortcut_manager::set_shortcut (_clear_workspace_action, "main_edit:clear_workspace"); } else @@ -2300,13 +2309,26 @@ QKeySequence no_key = QKeySequence (); + // file menu _open_action->setShortcut (no_key); _new_script_action->setShortcut (no_key); _new_function_action->setShortcut (no_key); - + _new_function_action->setShortcut (no_key); + _load_workspace_action->setShortcut (no_key); + _save_workspace_action->setShortcut (no_key); + _preferences_action->setShortcut (no_key); _exit_action->setShortcut (no_key); + // edit menu + //_copy_action->setShortcut (no_key); + //_paste_action->setShortcut (no_key); + //_undo_action->setShortcut (no_key); + _select_all_action->setShortcut (no_key); + _clear_clipboard_action->setShortcut (no_key); _find_files_action->setShortcut (no_key); + _clear_command_history_action->setShortcut (no_key); + _clear_command_window_action->setShortcut (no_key); + _clear_workspace_action->setShortcut (no_key); } diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/main-window.h --- a/libgui/src/main-window.h Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/main-window.h Fri Apr 04 11:50:14 2014 -0700 @@ -315,14 +315,21 @@ QAction *_new_script_action; QAction *_new_function_action; QAction *_open_action; + QAction *_new_figure_action; + QAction *_load_workspace_action; + QAction *_save_workspace_action; + QAction *_preferences_action; + QAction *_exit_action; QAction *_copy_action; QAction *_paste_action; QAction *_clear_clipboard_action; QAction *_undo_action; - + QAction *_clear_command_window_action; + QAction *_clear_command_history_action; + QAction *_clear_workspace_action; QAction *_find_files_action; - QAction *_exit_action; + QAction *_select_all_action; // Toolbars. QComboBox *_current_directory_combo_box; diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/module.mk --- a/libgui/src/module.mk Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/module.mk Fri Apr 04 11:50:14 2014 -0700 @@ -96,6 +96,7 @@ src/moc-terminal-dock-widget.cc \ src/moc-color-picker.cc \ src/moc-resource-manager.cc \ + src/moc-shortcut-manager.cc \ src/moc-welcome-wizard.cc \ src/moc-workspace-model.cc \ src/moc-workspace-view.cc \ @@ -133,6 +134,7 @@ src/qtinfo/webinfo.h \ src/resource-manager.h \ src/settings-dialog.h \ + src/shortcut-manager.h \ src/thread-manager.h \ src/terminal-dock-widget.h \ src/color-picker.h \ @@ -160,6 +162,7 @@ src/qtinfo/webinfo.cc \ src/resource-manager.cc \ src/settings-dialog.cc \ + src/shortcut-manager.cc \ src/thread-manager.cc \ src/terminal-dock-widget.cc \ src/color-picker.cc \ diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/octave-gui.cc --- a/libgui/src/octave-gui.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/octave-gui.cc Fri Apr 04 11:50:14 2014 -0700 @@ -48,6 +48,7 @@ #include "welcome-wizard.h" #include "resource-manager.h" +#include "shortcut-manager.h" #include "main-window.h" #include "octave-gui.h" #include "thread-manager.h" @@ -85,42 +86,11 @@ int m_result; }; -#if ! defined (__WIN32__) || defined (__CYGWIN__) -static int fdstderr = -1; -#endif +// Disable all Qt messages by default. -// Custom message handler for filtering some messages from Qt. - -void +static void message_handler (QtMsgType type, const char *msg) { -#if ! defined (__WIN32__) || defined (__CYGWIN__) - static FILE *errstream = fdopen (fdstderr, "a+"); -#else - static FILE *errstream = stderr; -#endif - - switch (type) - { - case QtDebugMsg: - gnulib::fprintf (errstream, "Debug: %s\n", msg); - break; - - case QtWarningMsg: - gnulib::fprintf (errstream, "Warning: %s\n", msg); - break; - - case QtCriticalMsg: - gnulib::fprintf (errstream, "Critical: %s\n", msg); - break; - - case QtFatalMsg: - gnulib::fprintf (errstream, "Fatal: %s\n", msg); - abort (); - - default: - break; - } } // If START_GUI is false, we still set up the QApplication so that we @@ -131,14 +101,11 @@ { octave_thread_manager::block_interrupt_signal (); -#if ! defined (__WIN32__) || defined (__CYGWIN__) - // Store the file descriptor associated with the STDERR stream. Send - // Qt messages there instead of to the STDERR stream that will be - // associated with the GUI command window. - fdstderr = gnulib::dup (STDERR_FILENO); -#endif + std::string show_gui_msgs = octave_env::getenv ("OCTAVE_SHOW_GUI_MESSAGES"); - qInstallMsgHandler (message_handler); + // Installing our handler suppresses the messages. + if (show_gui_msgs.empty ()) + qInstallMsgHandler (message_handler); if (start_gui) { @@ -192,6 +159,9 @@ octave_env::putenv ("TERM", "cygwin"); #endif + // shortcut manager + shortcut_manager::init_data (); + // Create and show main window. main_window w; diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/settings-dialog.cc --- a/libgui/src/settings-dialog.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/settings-dialog.cc Fri Apr 04 11:50:14 2014 -0700 @@ -25,6 +25,7 @@ #endif #include "resource-manager.h" +#include "shortcut-manager.h" #include "workspace-model.h" #include "settings-dialog.h" #include "ui-settings-dialog.h" @@ -57,6 +58,8 @@ { ui->setupUi (this); + shortcut_manager::fill_treewidget (ui->shortcuts_treewidget); + QSettings *settings = resource_manager::get_settings (); // restore last geometry @@ -191,6 +194,8 @@ settings->value ("terminal/fontName","Courier New").toString ()) ); ui->terminal_fontSize->setValue ( settings->value ("terminal/fontSize", 10).toInt ()); + ui->terminal_history_buffer->setValue ( + settings->value ("terminal/history_buffer",1000).toInt ()); // file browser ui->showFileSize->setChecked ( @@ -626,6 +631,8 @@ ui->terminal_cursorUseForegroundColor->isChecked ()); settings->setValue ("terminal/focus_after_command", ui->terminal_focus_command->isChecked ()); + settings->setValue ("terminal/history_buffer", + ui->terminal_history_buffer->value() ); // the cursor QString cursorType; @@ -671,6 +678,8 @@ write_terminal_colors (settings); + shortcut_manager::write_shortcuts (); + settings->setValue ("settings/last_tab",ui->tabWidget->currentIndex ()); settings->setValue ("settings/geometry",saveGeometry ()); settings->sync (); diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/settings-dialog.ui --- a/libgui/src/settings-dialog.ui Thu Apr 03 16:30:05 2014 -0700 +++ b/libgui/src/settings-dialog.ui Fri Apr 04 11:50:14 2014 -0700 @@ -32,7 +32,7 @@ - 1 + 6 @@ -1165,6 +1165,12 @@ + + + 40 + 20 + + @@ -1255,6 +1261,62 @@ + + + + 0 + + + + + 0 + + + 5000 + + + 20 + + + 1000 + + + + + + + (Changing buffer size clears history) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 100 + 20 + + + + History buffer Size + + + @@ -1271,19 +1333,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -1340,6 +1389,9 @@ Qt::Vertical + + QSizePolicy::Expanding + 20 @@ -1596,6 +1648,132 @@ + + + Shortcuts + + + + + + true + + + + + 0 + 0 + 678 + 378 + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + + + Enter a new shortcut by double clicking on the related row. + + + + + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 0 + 0 + + + + 0 + + + true + + + false + + + false + + + false + + + 3 + + + false + + + 120 + + + false + + + 64 + + + true + + + + Action + + + + + Default Shortcut + + + AlignLeft|AlignVCenter + + + + + Actual Shortcut + + + AlignLeft|AlignVCenter + + + + + + + + + + + + + + Network diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/shortcut-manager.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/shortcut-manager.cc Fri Apr 04 11:50:14 2014 -0700 @@ -0,0 +1,402 @@ +/* + +Copyright (C) 2014 Torsten + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "error.h" +#include "resource-manager.h" +#include "shortcut-manager.h" +#include "singleton-cleanup.h" + +shortcut_manager *shortcut_manager::instance = 0; + +shortcut_manager::shortcut_manager () +{ + setObjectName ("Shortcut_Manager"); +} + +shortcut_manager::~shortcut_manager () +{ +} + +bool +shortcut_manager::instance_ok (void) +{ + bool retval = true; + + if (! instance) + { + instance = new shortcut_manager (); + + if (instance) + singleton_cleanup_list::add (cleanup_instance); + } + + if (! instance) + { + ::error ("unable to create shortcut_manager object!"); + + retval = false; + } + + return retval; +} + +void +shortcut_manager::do_init_data () +{ + // actions of the main window + init (tr ("New File"), "main_file:new_file", QKeySequence::New ); + init (tr ("New Function"), "main_file:new_function", QKeySequence ("Ctrl+Shift+N") ); + init (tr ("New Figure"), "main_file:new_figure", QKeySequence () ); + init (tr ("Open File"), "main_file:open_file", QKeySequence::Open ); + init (tr ("Load Workspace"), "main_file:load_workspace", QKeySequence () ); + init (tr ("Save Workspace As"), "main_file:save_workspace", QKeySequence () ); + init (tr ("Preferences"), "main_file:preferences", QKeySequence () ); + init (tr ("Exit Octave"), "main_file:exit", QKeySequence::Quit ); + + init (tr ("Copy"), "main_edit:copy", QKeySequence::Copy); + init (tr ("Paste"), "main_edit:paste", QKeySequence::Paste); + init (tr ("Undo"), "main_edit:undo", QKeySequence::Undo); + init (tr ("Select All"), "main_edit:select_all", QKeySequence () ); + init (tr ("Clear Clipboard"), "main_edit:clear_clipboard", QKeySequence () ); + init (tr ("Find in Files"), "main_edit:find_in_files", QKeySequence (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_F) ); + init (tr ("Clear Command Window"), "main_edit:clear_command_window", QKeySequence () ); + init (tr ("Clear Command History"), "main_edit:clear_history", QKeySequence () ); + init (tr ("Clear Workspace"), "main_edit:clear_workspace", QKeySequence () ); + + // actions of the editor + init (tr ("Save File"), "editor_file:save", QKeySequence::Save ); + init (tr ("Save File As"), "editor_file:save_as", QKeySequence::SaveAs ); +} + +void +shortcut_manager::init (QString description, QString key, QKeySequence def_sc) +{ + QSettings *settings = resource_manager::get_settings (); + + settings->beginGroup ("shortcuts"); + QKeySequence actual = QKeySequence (settings->value (key, def_sc).toString ()); + settings->endGroup (); + + shortcut_t shortcut_info; + shortcut_info.description = description; + shortcut_info.settings_key = key; + shortcut_info.actual_sc = actual; + shortcut_info.default_sc = def_sc; + _sc << shortcut_info; + + if (! actual.isEmpty ()) + _shortcut_hash[actual] = _sc.count (); // offset of 1 to avoid 0 + _action_hash[key] = _sc.count (); // offset of 1 to avoid 0 +} + +void +shortcut_manager::do_fill_treewidget (QTreeWidget *tree_view) +{ + _dialog = 0; + _level_hash.clear (); + + tree_view->header ()->setResizeMode (QHeaderView::ResizeToContents); + + QTreeWidgetItem *main = new QTreeWidgetItem (tree_view); + main->setText (0, tr ("Main")); + main->setExpanded (true); + QTreeWidgetItem *main_file = new QTreeWidgetItem (main); + main_file->setText (0, tr ("File")); + QTreeWidgetItem *main_edit = new QTreeWidgetItem (main); + main_edit->setText (0, tr ("Edit")); + QTreeWidgetItem *main_debug = new QTreeWidgetItem (main); + main_debug->setText (0, tr ("Debug")); + QTreeWidgetItem *main_window = new QTreeWidgetItem (main); + main_window->setText (0, tr ("Window")); + QTreeWidgetItem *main_help = new QTreeWidgetItem (main); + main_help->setText (0, tr ("Help")); + QTreeWidgetItem *main_news = new QTreeWidgetItem (main); + main_news->setText (0, tr ("News")); + + _level_hash["main_file"] = main_file; + _level_hash["main_edit"] = main_edit; + _level_hash["main_debug"] = main_debug; + _level_hash["main_window"] = main_window; + _level_hash["main_help"] = main_help; + _level_hash["main_news"] = main_news; + + QTreeWidgetItem *editor = new QTreeWidgetItem (tree_view); + editor->setText (0, tr ("Editor")); + editor->setExpanded (true); + QTreeWidgetItem *editor_file = new QTreeWidgetItem (editor); + editor_file->setText (0, tr ("File")); + QTreeWidgetItem *editor_edit = new QTreeWidgetItem (editor); + editor_edit->setText (0, tr ("Edit")); + QTreeWidgetItem *editor_view = new QTreeWidgetItem (editor); + editor_view->setText (0, tr ("View")); + QTreeWidgetItem *editor_debug = new QTreeWidgetItem (editor); + editor_debug->setText (0, tr ("Debug")); + QTreeWidgetItem *editor_run = new QTreeWidgetItem (editor); + editor_run->setText (0, tr ("Run")); + QTreeWidgetItem *editor_help = new QTreeWidgetItem (editor); + editor_help->setText (0, tr ("Help")); + + _level_hash["editor_file"] = editor_file; + _level_hash["editor_edit"] = editor_edit; + _level_hash["editor_view"] = editor_view; + _level_hash["editor_debug"] = editor_debug; + _level_hash["editor_run"] = editor_run; + _level_hash["editor_help"] = editor_help; + + connect (tree_view, SIGNAL (itemDoubleClicked (QTreeWidgetItem*, int)), + this, SLOT (handle_double_clicked (QTreeWidgetItem*, int))); + + for (int i = 0; i < _sc.count (); i++) + { + shortcut_t shortcut_info = _sc.at (i); + + QTreeWidgetItem* section = _level_hash[shortcut_info.settings_key.section(':',0,0)]; + QTreeWidgetItem* tree_item = new QTreeWidgetItem (section); + + tree_item->setText (0, shortcut_info.description); + tree_item->setText (1, shortcut_info.default_sc); + tree_item->setText (2, shortcut_info.actual_sc); + + _item_index_hash[tree_item] = i + 1; // index+1 to avoid 0 + _index_item_hash[i] = tree_item; + } +} + +void +shortcut_manager::do_write_shortcuts () +{ + QSettings *settings = resource_manager::get_settings (); + + settings->beginGroup ("shortcuts"); + for (int i = 0; i < _sc.count (); i++) + settings->setValue(_sc.at (i).settings_key, _sc.at (i).actual_sc.toString ()); + settings->endGroup (); + + settings->sync (); + + delete _dialog; +} + +void +shortcut_manager::do_set_shortcut (QAction* action, const QString& key) +{ + QSettings *settings = resource_manager::get_settings (); + + int index = _action_hash[key] - 1; + + action->setShortcut ( + settings->value ("shortcuts/" + key, _sc.at (index).default_sc).toString ()); +} + +void +shortcut_manager::handle_double_clicked (QTreeWidgetItem* item, int) +{ + int i = _item_index_hash[item]; + if (i == 0) + return; // top-level-item clicked + + shortcut_dialog (i-1); // correct to index starting at 0 +} + +void +shortcut_manager::shortcut_dialog (int index) +{ + if (! _dialog) + { + _dialog = new QDialog (this); + + _dialog->setWindowTitle (tr ("Enter new Shortcut")); + + QVBoxLayout *box = new QVBoxLayout(_dialog); + + QLabel *help = new QLabel (tr ("Apply the desired shortcut or click " + "on the right button to reset the " + "shortcut to its default.")); + help->setWordWrap (true); + box->addWidget (help); + + QCheckBox *direct = new QCheckBox (tr ("Enter shortcut directly by performing it")); + direct->setCheckState (Qt::Checked); + box->addWidget (direct); + + QGridLayout *grid = new QGridLayout(); + + QLabel *actual = new QLabel (tr ("Actual shortcut")); + _edit_actual = new enter_shortcut (_dialog); + _edit_actual->setAlignment (Qt::AlignHCenter); + grid->addWidget (actual, 0, 0); + grid->addWidget (_edit_actual, 0, 1); + + QLabel *def = new QLabel (tr ("Default shortcut")); + _label_default = new QLabel (_dialog); + _label_default->setAlignment (Qt::AlignHCenter); + grid->addWidget (def, 1, 0); + grid->addWidget (_label_default, 1, 1); + + QPushButton *set_default = new QPushButton (tr ("Set to default")); + grid->addWidget (set_default, 0, 2); + connect (set_default, SIGNAL (clicked ()), + this, SLOT (shortcut_dialog_set_default ())); + + box->addLayout (grid); + + QDialogButtonBox *button_box = new QDialogButtonBox (QDialogButtonBox::Ok + | QDialogButtonBox::Cancel); + QList buttons = button_box->buttons (); + for (int i = 0; i < buttons.count (); i++) + buttons.at (i)->setShortcut (QKeySequence ()); + connect(button_box, SIGNAL (accepted ()), _dialog, SLOT (accept ())); + connect(button_box, SIGNAL (rejected ()), _dialog, SLOT (reject ())); + box->addWidget (button_box); + + _dialog->setLayout (box); + + connect (direct, SIGNAL (stateChanged (int)), + _edit_actual, SLOT (handle_direct_shortcut (int))); + connect (_dialog, SIGNAL (finished (int)), + this, SLOT (shortcut_dialog_finished (int))); + + } + + _edit_actual->setText (_sc.at (index).actual_sc); + _label_default->setText (_sc.at (index).default_sc); + _handled_index = index; + + _edit_actual->setFocus (); + _dialog->setFocusProxy (_edit_actual); + _dialog->exec (); +} + +void +shortcut_manager::shortcut_dialog_finished (int result) +{ + if (result == QDialog::Rejected) + return; + + int double_index = _shortcut_hash[_edit_actual->text()] - 1; + + if (double_index >= 0 && double_index != _handled_index) + { + int ret = QMessageBox::warning(this, tr("Double Shortcut"), + tr ("The chosen shortcut\n \"%1\"\n" + "is already used for the action\n \"%2\".\n" + "Do you want to use the shortcut anyhow removing it " + "from the previous action?") + .arg (_edit_actual->text()) + .arg (_sc.at (double_index).description), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + + if (ret == QMessageBox::Yes) + { + shortcut_t double_shortcut = _sc.at (double_index); + double_shortcut.actual_sc = QKeySequence (); + _sc.replace (double_index, double_shortcut); + _index_item_hash[double_index]->setText (1, QKeySequence ()); + } + else + return; + } + + shortcut_t shortcut = _sc.at (_handled_index); + if (! shortcut.actual_sc.isEmpty ()) + _shortcut_hash.remove (shortcut.actual_sc); + shortcut.actual_sc = _edit_actual->text(); + _sc.replace (_handled_index, shortcut); + + _index_item_hash[_handled_index]->setText (2, shortcut.actual_sc); + + if (! shortcut.actual_sc.isEmpty ()) + _shortcut_hash[shortcut.actual_sc] = _handled_index + 1; // index+1 to avoid 0 +} + +void +shortcut_manager::shortcut_dialog_set_default () +{ + _edit_actual->setText (_label_default->text ()); +} + + + +enter_shortcut::enter_shortcut (QWidget *p) : QLineEdit (p) +{ + _direct_shortcut = true; +} + +enter_shortcut::~enter_shortcut () +{ +} + +void +enter_shortcut::handle_direct_shortcut (int state) +{ + if (state) + _direct_shortcut = true; + else + _direct_shortcut = false; +} + +void +enter_shortcut::keyPressEvent (QKeyEvent *e) +{ + if (! _direct_shortcut) + { + QLineEdit::keyPressEvent (e); + return; + } + + if (e->type () == QEvent::KeyPress) + { + int key = e->key (); + + if (key == Qt::Key_unknown || key == 0 || key >= 16777248) + return; + + Qt::KeyboardModifiers modifiers = e->modifiers (); + + if(modifiers & Qt::ShiftModifier) + key += Qt::SHIFT; + if(modifiers & Qt::ControlModifier) + key += Qt::CTRL; + if(modifiers & Qt::AltModifier) + key += Qt::ALT; + if(modifiers & Qt::MetaModifier) + key += Qt::META; + + setText (QKeySequence(key)); + } +} + diff -r aff86394c201 -r 37d5a2bb4160 libgui/src/shortcut-manager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/shortcut-manager.h Fri Apr 04 11:50:14 2014 -0700 @@ -0,0 +1,139 @@ +/* + +Copyright (C) 2014 Torsten + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#ifndef SHORTCUT_MANAGER_H +#define SHORTCUT_MANAGER_H + +#include +#include +#include +#include +#include + + +class enter_shortcut : public QLineEdit +{ + Q_OBJECT + +public: + enter_shortcut (QWidget *p = 0); + ~enter_shortcut (); + + virtual void keyPressEvent (QKeyEvent *e); + +public slots: + void handle_direct_shortcut (int); + +private: + bool _direct_shortcut; + +}; + + +class shortcut_manager : public QWidget +{ + Q_OBJECT + +public: + shortcut_manager (); + ~shortcut_manager (); + + static void init_data () + { + if (instance_ok ()) + instance->do_init_data (); + } + + static void write_shortcuts () + { + if (instance_ok ()) + instance->do_write_shortcuts (); + } + + static void set_shortcut (QAction *action, const QString& key) + { + if (instance_ok ()) + instance->do_set_shortcut (action, key); + } + + static void fill_treewidget (QTreeWidget *tree_view) + { + if (instance_ok ()) + instance->do_fill_treewidget (tree_view); + } + +public slots: + +signals: + +protected: + +protected slots: + + void handle_double_clicked (QTreeWidgetItem*, int); + void shortcut_dialog_finished (int); + void shortcut_dialog_set_default (); + +private: + + static shortcut_manager *instance; + static void cleanup_instance (void) { delete instance; instance = 0; } + + // No copying! + + shortcut_manager (const shortcut_manager&); + shortcut_manager& operator = (const shortcut_manager&); + + static bool instance_ok (void); + + void init (QString, QString, QKeySequence); + void do_init_data (); + void do_write_shortcuts (); + void do_set_shortcut (QAction *action, const QString& key); + void do_fill_treewidget (QTreeWidget *tree_view); + void shortcut_dialog (int); + + struct shortcut_t + { + QString description; + QString settings_key; + QKeySequence actual_sc; + QKeySequence default_sc; + QTreeWidgetItem *tree_item; + }; + + QList _sc; + QHash _shortcut_hash; + QHash _action_hash; + QHash _level_hash; + QHash _index_item_hash; + QHash _item_index_hash; + + QDialog *_dialog; + enter_shortcut *_edit_actual; + QLabel *_label_default; + int _handled_index; + +}; + + +#endif // SHORTCUT_MANAGER_H diff -r aff86394c201 -r 37d5a2bb4160 libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libinterp/corefcn/oct-stream.cc Fri Apr 04 11:50:14 2014 -0700 @@ -3394,6 +3394,18 @@ template static void +convert_chars (const void *data, void *conv_data, octave_idx_type n_elts) +{ + const T *tt_data = static_cast (data); + + V *vt_data = static_cast (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + vt_data[i] = tt_data[i]; +} + +template +static void convert_ints (const T *data, void *conv_data, octave_idx_type n_elts, bool swap) { @@ -3403,6 +3415,9 @@ for (octave_idx_type i = 0; i < n_elts; i++) { + // Yes, we want saturation semantics when converting to an integer + // type. + V val (data[i]); vt_data[i] = val.value (); @@ -3413,6 +3428,20 @@ } template +class ultimate_element_type +{ +public: + typedef T type; +}; + +template +class ultimate_element_type > +{ +public: + typedef T type; +}; + +template static bool convert_data (const T *data, void *conv_data, octave_idx_type n_elts, oct_data_conv::data_type output_type, @@ -3427,18 +3456,26 @@ bool do_float_conversion = flt_fmt != oct_mach_info::float_format (); - // We use octave_intN classes here instead of converting directly to - // intN_t so that we get integer saturation semantics. + typedef typename ultimate_element_type::type ult_elt_type; switch (output_type) { case oct_data_conv::dt_char: + convert_chars (data, conv_data, n_elts); + break; + case oct_data_conv::dt_schar: + convert_chars (data, conv_data, n_elts); + break; + + case oct_data_conv::dt_uchar: + convert_chars (data, conv_data, n_elts); + break; + case oct_data_conv::dt_int8: convert_ints (data, conv_data, n_elts, swap); break; - case oct_data_conv::dt_uchar: case oct_data_conv::dt_uint8: convert_ints (data, conv_data, n_elts, swap); break; diff -r aff86394c201 -r 37d5a2bb4160 libinterp/dldfcn/__init_fltk__.cc --- a/libinterp/dldfcn/__init_fltk__.cc Thu Apr 03 16:30:05 2014 -0700 +++ b/libinterp/dldfcn/__init_fltk__.cc Fri Apr 04 11:50:14 2014 -0700 @@ -42,6 +42,10 @@ #ifdef HAVE_FLTK +#if defined (HAVE_X_WINDOWS) +#include +#endif + #include #include #include @@ -73,6 +77,7 @@ #include "cmd-edit.h" #include "lo-ieee.h" +#include "oct-env.h" #include "display.h" #include "file-ops.h" @@ -674,6 +679,14 @@ Fl_Menu_Bar* menubar; }; +#if defined (HAVE_X_WINDOWS) +static int +xerror_handler (Display *, XErrorEvent *) +{ + return 0; +} +#endif + class plot_window : public Fl_Window { friend class fltk_uimenu; @@ -762,7 +775,18 @@ // Set WM_CLASS which allows window managers to properly group // related windows. Otherwise, the class is just "FLTK" xclass ("Octave"); + show (); + +#if defined (HAVE_X_WINDOWS) + std::string show_gui_msgs + = octave_env::getenv ("OCTAVE_SHOW_GUI_MESSAGES"); + + // Installing our handler suppresses the messages. + if (show_gui_msgs.empty ()) + XSetErrorHandler (xerror_handler); +#endif + if (fp.get_currentaxes ().ok ()) show_canvas (); else diff -r aff86394c201 -r 37d5a2bb4160 scripts/image/imread.m --- a/scripts/image/imread.m Thu Apr 03 16:30:05 2014 -0700 +++ b/scripts/image/imread.m Fri Apr 04 11:50:14 2014 -0700 @@ -75,7 +75,17 @@ ## Controls the image region that is read. Takes as value a cell array ## with two arrays of 3 elements @code{@{@var{rows} @var{cols}@}}. The ## elements in the array are the start, increment and end pixel to be -## read. If the increment value is omitted, defaults to 1. +## read. If the increment value is omitted, defaults to 1. For example, +## the following are all equivalent: +## +## @example +## @group +## imread (filename, "PixelRegion", @{[200 600] [300 700]@}); +## imread (filename, "PixelRegion", @{[200 1 600] [300 1 700]@}); +## imread (filename)(200:600, 300:700); +## @end group +## @end example +## ## @end table ## ## @seealso{imwrite, imfinfo, imformats} @@ -130,6 +140,24 @@ %! assert (A(:,:,2), uint8 ([0, 255, 0; 255, 28, 255; 0, 255, 0])); %! assert (A(:,:,3), uint8 ([0, 255, 0; 255, 36, 255; 0, 255, 0])); +%!function [r, cmap, a] = write_and_read (w, varargin) +%! filename = [tmpnam() ".tif"]; +%! unwind_protect +%! imwrite (w, filename); +%! [r, cmap, a] = imread (filename, varargin{:}); +%! unwind_protect_cleanup +%! unlink (filename); +%! end_unwind_protect +%!endfunction + +## test PixelRegion option +%!testif HAVE_MAGICK +%! w = randi (255, 100, 100, "uint8"); +%! [r, cmap, a] = write_and_read (w, "PixelRegion", {[50 70] [20 40]}); +%! assert (r, w(50:70, 20:40)) +%! [r, cmap, a] = write_and_read (w, "PixelRegion", {[50 2 70] [20 3 40]}); +%! assert (r, w(50:2:70, 20:3:40)) + ## If a file does not exist, it's the job of imread to check the file ## exists before sending it over to __imread__ or whatever function ## is defined in imformats to handle that specific format. This is the diff -r aff86394c201 -r 37d5a2bb4160 scripts/optimization/fminunc.m --- a/scripts/optimization/fminunc.m Thu Apr 03 16:30:05 2014 -0700 +++ b/scripts/optimization/fminunc.m Fri Apr 04 11:50:14 2014 -0700 @@ -21,16 +21,16 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} fminunc (@var{fcn}, @var{x0}) ## @deftypefnx {Function File} {} fminunc (@var{fcn}, @var{x0}, @var{options}) -## @deftypefnx {Function File} {[@var{x}, @var{fvec}, @var{info}, @var{output}, @var{grad}, @var{hess}] =} fminunc (@var{fcn}, @dots{}) +## @deftypefnx {Function File} {[@var{x}, @var{fval}, @var{info}, @var{output}, @var{grad}, @var{hess}] =} fminunc (@var{fcn}, @dots{}) ## Solve an unconstrained optimization problem defined by the function ## @var{fcn}. ## -## @var{fcn} should accepts a vector (array) defining the unknown variables, +## @var{fcn} should accept a vector (array) defining the unknown variables, ## and return the objective function value, optionally with gradient. -## In other words, this function attempts to determine a vector @var{x} such -## that @code{@var{fcn} (@var{x})} is a local minimum. -## @var{x0} determines a starting guess. The shape of @var{x0} is preserved -## in all calls to @var{fcn}, but otherwise is treated as a column vector. +## @code{fminunc} attempts to determine a vector @var{x} such that +## @code{@var{fcn} (@var{x})} is a local minimum. @var{x0} determines a +## starting guess. The shape of @var{x0} is preserved in all calls to +## @var{fcn}, but otherwise is treated as a column vector. ## @var{options} is a structure specifying additional options. ## Currently, @code{fminunc} recognizes these options: ## @qcode{"FunValCheck"}, @qcode{"OutputFcn"}, @qcode{"TolX"}, @@ -39,42 +39,46 @@ ## @qcode{"TypicalX"}, @qcode{"AutoScaling"}. ## ## If @qcode{"GradObj"} is @qcode{"on"}, it specifies that @var{fcn}, -## called with 2 output arguments, also returns the Jacobian matrix -## of right-hand sides at the requested point. @qcode{"TolX"} specifies -## the termination tolerance in the unknown variables, while -## @qcode{"TolFun"} is a tolerance for equations. Default is @code{1e-7} -## for both @qcode{"TolX"} and @qcode{"TolFun"}. +## when called with 2 output arguments, also returns the Jacobian matrix +## of partial first derivatives at the requested point. +## @code{TolX} specifies the termination tolerance for the unknown variables +## @var{x}, while @code{TolFun} is a tolerance for the objective function +## value @var{fval}. The default is @code{1e-7} for both options. ## -## For description of the other options, see @code{optimset}. +## For a description of the other options, see @code{optimset}. ## -## On return, @var{fval} contains the value of the function @var{fcn} -## evaluated at @var{x}, and @var{info} may be one of the following values: +## On return, @var{x} is the location of the minimum and @var{fval} contains +## the value of the objective function at @var{x}. @var{info} may be one of the +## following values: ## ## @table @asis ## @item 1 ## Converged to a solution point. Relative gradient error is less than -## specified -## by TolFun. +## specified by @code{TolFun}. ## ## @item 2 -## Last relative step size was less that TolX. +## Last relative step size was less than @code{TolX}. ## ## @item 3 -## Last relative decrease in function value was less than TolF. +## Last relative change in function value was less than @code{TolFun}. ## ## @item 0 -## Iteration limit exceeded. +## Iteration limit exceeded---either maximum numer of algorithm iterations +## @code{MaxIter} or maximum number of function evaluations @code{MaxFunEvals}. +## +## @item -1 +## Alogrithm terminated by @code{OutputFcn}. ## ## @item -3 ## The trust region radius became excessively small. ## @end table ## -## Optionally, fminunc can also yield a structure with convergence statistics -## (@var{output}), the output gradient (@var{grad}) and approximate Hessian -## (@var{hess}). +## Optionally, @code{fminunc} can return a structure with convergence statistics +## (@var{output}), the output gradient (@var{grad}) at the solution @var{x}, +## and approximate Hessian (@var{hess}) at the solution @var{x}. ## -## Notes: If you only have a single nonlinear equation of one variable then -## using @code{fminbnd} is usually a much better idea. The algorithm used is a +## Notes: If have only a single nonlinear equation of one variable then using +## @code{fminbnd} is usually a much better idea. The algorithm used is a ## gradient search which depends on the objective function being differentiable. ## If the function has discontinuities it may be better to use a derivative-free ## algorithm such as @code{fminsearch}. @@ -221,7 +225,7 @@ delta = factor * max (xn, 1); endif - ## FIXME -- why tolf*n*xn? If abs (e) ~ abs(x) * eps is a vector + ## FIXME: why tolf*n*xn? If abs (e) ~ abs(x) * eps is a vector ## of perturbations of x, then norm (hesr*e) <= eps*xn, i.e. by ## tolf ~ eps we demand as much accuracy as we can expect. if (norm (grad) <= tolf*n*xn) @@ -287,13 +291,13 @@ x += s; xn = norm (dg .* x); fval = fval1; - nsuciter ++; + nsuciter++; suc = true; endif niter ++; - ## FIXME: should outputfcn be only called after a successful iteration? + ## FIXME: should outputfcn be called only after a successful iteration? if (! isempty (outfcn)) optimvalues.iter = niter; optimvalues.funccount = nfev; @@ -344,8 +348,7 @@ endfunction -## An assistant function that evaluates a function handle and checks for -## bad results. +## A helper function that evaluates a function and checks for bad results. function [fx, gx] = guarded_eval (fun, x) if (nargout > 1) [fx, gx] = fun (x); diff -r aff86394c201 -r 37d5a2bb4160 test/io.tst --- a/test/io.tst Thu Apr 03 16:30:05 2014 -0700 +++ b/test/io.tst Fri Apr 04 11:50:14 2014 -0700 @@ -439,6 +439,18 @@ %! assert (__prog_output_assert__ ("ok")); %!test +%! x = char (128:255)'; +%! nm = tmpnam (); +%! id = fopen (nm, "wb"); +%! fwrite (id, x); +%! fclose (id); +%! id = fopen (nm, "rb"); +%! y = fread (id, Inf, "uchar=>char"); +%! fclose (id); +%! unlink (nm); +%! assert (x, y); + +%!test %! nm = tmpnam (); %! id = fopen (nm, "wb"); %! if (id > 0)